我正在使用Jasmine来编写我的测试,但我想我对任何其他测试框架都有这个问题。假设我们有一个模块foo
,它有两个函数Bar
和Baz
,它们是构造函数(但可能只是普通函数):
var Bar = exports.Bar = function Bar() {
this.baz = new Baz();
};
var Baz = exports.Baz = function Baz() {
};
现在我想测试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();
});
});
问题是此测试将失败,因为Bar
使用变量Baz
实例化新Baz
,该变量无法从外部更改。使用spyOn()
进行交换的唯一方法是exports.Baz
。
显而易见的解决方案是写this.baz = new exports.Baz();
,但有点尴尬。如果我想在模块中使用更多函数,我必须始终使用exports.
前缀调用所有函数。这里还有其他方法吗?
答案 0 :(得分:1)
如果你能以某种方式解耦这两个类,比如允许Baz类的其他实现被赋予bar,那么我认为这是最好的方法,你应该去实现它。
但如果您真的希望能够将exports.Baz
称为Baz
,那么我可以使用with
找到一种方法。
据说使用with
通常是一种不好的做法,应该避免使用,我不会在我自己的代码中使用它,但这是解决它的一种方法,甚至可以{{3}只要你知道你在做什么。
这就是:
with(exports) {
exports.Bar = function Bar() {
console.log('this is bar!');
this.baz = new Baz();
};
exports.Baz = function Baz() {
console.log('original baz!');
};
}
在另一个模块中,如果您将foo.Baz
更改为其他内容,则foo中的Baz
也会查找它。
我仍然建议找到一种方法让这两个类彼此独立,然后你可以给Bar吧你想要的任何Baz实现。