[英]Mocking a constructor (or other function) in a Node.js module outside of this module
I'm using Jasmine to write my tests, but I guess I'd have this problem with any other testing framework. 我正在使用Jasmine编写我的测试,但我想我对任何其他测试框架都有这个问题。 Let's say that we have a module
foo
with two functions, Bar
and Baz
, which are constructors (but could be just normal functions): 假设我们有一个带有两个函数的模块
foo
, Bar
和Baz
,它们是构造函数(但可能只是普通函数):
var Bar = exports.Bar = function Bar() {
this.baz = new Baz();
};
var Baz = exports.Baz = function Baz() {
};
Now I would like to test Bar
, but with a fake Baz
implementation: 现在我想测试
Bar
,但是使用假的Baz
实现:
var foo = require('foo');
describe("foo.Bar", function() {
it("initializes its own Baz", function() {
spyOn(foo, 'Baz'); // this replaces foo.Baz with a fake implementation
var bar = new foo.Bar();
expect(foo.Baz).toHaveBeenCalled();
});
});
The problem is that this test will fail, because Bar
instantiates a new Baz
using the variable Baz
, which cannot be changed from outside. 问题是,这个测试将失败,因为
Bar
实例化一个新Baz
使用变量Baz
,不能从外部改变。 The only thing that got swapped by using spyOn()
is exports.Baz
. 这得到了通过交换的唯一的事情
spyOn()
是exports.Baz
。
The obvious solution is to write this.baz = new exports.Baz();
显而易见的解决方案是编写
this.baz = new exports.Baz();
but it kind of feels awkward. 但它有点尴尬。 If I have more functions which I want to use inside my module, I would have to always call all of them using the
exports.
如果我想在模块中使用更多函数,我必须始终使用
exports.
调用所有函数exports.
prefix. 字首。 Is there any other approach here?
这里有其他方法吗?
If you can somehow decouple these two classes, like allow other implementation of the Baz class to be given to bar, then I think that's the best way and you should go for it. 如果你能以某种方式解耦这两个类,比如允许Baz类的其他实现被赋予bar,那么我认为这是最好的方法,你应该去实现它。
But if you really want to be able to be able to refer to exports.Baz
as Baz
, then there's one way that I could think of, using with
. 但如果你真的希望能够能够参考
exports.Baz
为Baz
,再有就是,我能想到的,使用一种方式with
。
It is said that using with
is generally a bad practice and should be avoided, I wouldn't use it in my own code, but this is one way to solve it and can even be a legimate use , as long as you know what you are doing. 据说使用
with
通常是一种不好的做法,应该避免,我不会在我自己的代码中使用它,但这是解决它的一种方法,甚至可以是一个有效的用途 ,只要你知道你是什么是做。
Here it goes: 在这里:
with(exports) {
exports.Bar = function Bar() {
console.log('this is bar!');
this.baz = new Baz();
};
exports.Baz = function Baz() {
console.log('original baz!');
};
}
In another module if you change foo.Baz
to something else, Baz
inside foo will also look up to it. 在另一个模块中,如果你将
foo.Baz
更改为其他内容,那么foo中的Baz
也会查找它。
I would still recommend finding a way to make these two classes independent of each other and then you can just give Bar whatever implementation of Baz you want. 我仍然建议找到一种方法让这两个类彼此独立,然后你可以给Bar,无论你想要什么Baz的实现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.