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

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

本文关键字:函数 调用 是否 ES6 另一个 模块 一个 测试 js Sinon 使用      更新时间:2023-09-26

我想测试 ES6 模块中的一个函数是否使用 Sinon.js 调用另一个函数。以下是我正在做的事情的基本布局:

傅.js

export function bar() {
 baz();
}
export function baz() {
 ...
}

测试.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。在标准的"黑盒测试"中,你不关心某件事是如何完成的,你只关心它产生了什么副作用。为此,测试您是否发生了预期的副作用,并且没有采取任何其他措施。