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

Test that a function calls another function in an ES6 module with Sinon.js

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

根据我在网上看到的内容,我想知道按原样布局的代码是否有可能做到这一点,或者我是否需要对其进行重组以获得我想要的内容。

您认为模块当前的结构方式不可能做到这一点是对的。

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

确实可以访问导出的属性,但是您不能改变这些属性,因此您不能影响模块。

一种改变方法是使用如下代码:

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

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

export default obj;

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

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

此外,您应该考虑您是否真的关心 baz 是否被调用。在标准 "black-box testing" 中,您不关心 如何 某事是如何完成的,您只关心它产生的副作用。为此,测试是否发生了您预期的副作用,并且没有做任何其他事情。