我無法找到一種方法來存根從該函數定義的相同模組中呼叫的函數(存根似乎不起作用)。這是一個例子:
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
希望這是有道理的!