测试函数使用Sinon.js调用ES6模块中的另一个函数

时间:2016-01-31 07:22:21

标签: javascript ecmascript-6 sinon

我想测试一个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做的事情做一些基本的断言,但我显然不想这样做。

从我在网上看到的情况来看,我想知道这样的代码是否可行,或者我是否需要对其进行重组以获得我想要的内容。

1 个答案:

答案 0 :(得分:12)

你认为这不可能与模块目前的结构方式有关。

执行代码时,baz内的function bar引用将针对本地实现进行解析。您无法修改,因为在模块代码之外,无法访问内部。

执行可以访问导出的属性,但您无法改变这些属性,因此您无法影响该模块。

改变方法的一种方法是使用这样的代码:

let obj = {};
obj.bar = function () {
 this.baz();
}

obj.baz = function() {
 ...
}

export default obj;

现在,如果您在导入的对象中覆盖baz,则影响bar的内部。

话虽如此,感觉非常笨重。存在其他控制行为的方法,例如依赖注入。

此外,您应该考虑是否真的关心baz是否被调用。在标准的"黑盒测试"中,你不关心如何完成某些事情,你只关心它产生的副作用。为此,测试你预期的副作用是否发生,以及没有其他事情发生。