我无法找到一种方法来存储从同一模块中调用的函数这个函数的定义(存根似乎不起作用)。这是一个例子:
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
会起作用,但这不是我在这里要做的。我也知道在foo
方法中使用关键字bar
调用this
也会有效,我对在这种情况下使用this
感到困惑(因为我没有使用OOP。)
答案 0 :(得分:9)
我刚试过这个。它就像魅力一样。
'use strict'
function foo () {
return 'foo';
}
exports.foo = foo;
function bar () {
return exports.foo(); // <--- notice
}
exports.bar = bar;
解释
当您执行sinon.stub(myModule, 'foo').returns('foo2')
时,sinon
将exported
对象的foo
与您foo
内的实际myModule.js
函数存根...您必须知道,foo
可以从模块外部访问。因此,当您设置exports.foo
时,导出的对象exports.foo
会存储foo
的ref。当您致电sinon.stub(myModule, 'foo').returns('foo2')
时,sinon
会存根exports.foo
而非实际foo
希望这是有道理的!
答案 1 :(得分:0)
我对使用exports
有点警惕,因为它有点神奇(例如,当您使用Typescript进行编码时,您永远不会直接使用它),所以我想提出一个替代解决方案,不幸的是,仍然需要修改源代码,这仅仅是将要存根的函数包装到对象中
export const fooWrapper = {
foo() {...}
}
function bar () {
return fooWrapper.foo()
}
还有sinon.stub(fooWrapper, 'foo')
。只为进行测试而不得不像这样包装起来有点可惜,但至少它是显式的,并且在Typescript中是安全的(与exports
(键入any
相反)。