我无法找到一种方法来存根从该函数定义的同一模块中调用的函数(存根似乎不起作用)。这是一个例子:
myModule.js:
'use strict' function foo () { return 'foo' } exports.foo = foo function bar () { return foo() } exports.bar = bar
myModule.test.js:
'use strict' const chai = require('chai') const sinon = require('sinon') chai.should() const myModule = require('./myModule') describe('myModule', () => { describe('bar', () => { it('should return foo', () => { myModule.bar().should.equal('foo') // succeeds }) describe('when stubbed', () => { before(() => { sinon.stub(myModule, 'foo').returns('foo2') // this stub seems ignored }) it('should return foo2', () => { myModule.bar().should.equal('foo2') // fails }) }) }) })
这让我想起了(几乎)不可存根的 Java 静态函数。
知道如何实现我想要做的事情吗?我知道在不同的模块中提取 foo
会起作用,但这不是我在这里想要做的。我还知道,在 bar
方法中使用关键字 this
调用 foo
也会起作用,我对在这种情况下使用 ̀this
感到困惑(因为我没有使用 OOP)。
我对使用
exports
有点谨慎,因为它有点神奇(例如,当你在 Typescript 中编码时,你从不直接使用它),所以我想提出一个替代方案解决方案,不幸的是仍然需要修改源代码,只是将要存根的函数包装到对象中:和
sinon.stub(fooWrapper, 'foo')
。只为了测试而必须这样包装有点遗憾,但至少它在 Typescript 中是显式的且类型安全的(与输入为any
的exports
相反)。我刚刚测试了这个。它就像魅力一样起作用。
当您执行
sinon.stub(myModule, 'foo').returns('foo2')
时,sinon
会存根导出
对象的foo
并不是myModule.js
中实际的foo
函数...正如你必须知道的那样,foo
是可从模块外部访问。因此,当您设置exports.foo
时,导出的对象exports.foo
会存储foo
的 ref。当您调用sinon.stub(myModule, 'foo').returns('foo2')
时,sinon
将存根exports.foo
并不是实际的foo
希望这是有道理的!