我想测试一个ES6模块中的函数使用Sinon.js调用另一个函数。这是我正在做的事情的基本布局:
foo.js
export function bar() {
baz();
}
export function baz() {
...
}
test.js
import sinon from 'sinon';
import * as Foo from '.../foo';
describe('bar', function() {
it('should call baz', function() {
let spy = sinon.spy(Foo, 'baz');
spy.callCount.should.eql(0);
Foo.bar();
spy.calledOnce.should.eql(true);
});
});
但间谍没有接听baz()
的电话。还有其他方法可以设置模块或测试以允许sinon选择它吗?我的另一种选择是对baz做的事情做一些基本的断言,但我显然不想这样做。
从我在网上看到的情况来看,我想知道这样的代码是否可行,或者我是否需要对其进行重组以获得我想要的内容。
答案 0 :(得分:12)
你认为这不可能与模块目前的结构方式有关。
执行代码时,baz
内的function bar
引用将针对本地实现进行解析。您无法修改,因为在模块代码之外,无法访问内部。
您执行可以访问导出的属性,但您无法改变这些属性,因此您无法影响该模块。
改变方法的一种方法是使用这样的代码:
let obj = {};
obj.bar = function () {
this.baz();
}
obj.baz = function() {
...
}
export default obj;
现在,如果您在导入的对象中覆盖baz
,则将影响bar
的内部。
话虽如此,感觉非常笨重。存在其他控制行为的方法,例如依赖注入。
此外,您应该考虑是否真的关心baz
是否被调用。在标准的"黑盒测试"中,你不关心如何完成某些事情,你只关心它产生的副作用。为此,测试你预期的副作用是否发生,以及没有其他事情发生。