请帮助我了解Jest模拟。
我已经在文件中添加了一些虚拟函数:
// actions.js
export function f1() {
return 1
}
export function calls_f1() {
f1()
}
然后在我的测试文件中,我试图了解如何检查一个函数是否调用另一个函数:
import * as actions from './actions.js'
describe("MOCKS", () => {
actions.f1 = jest.fn();
actions.calls_f1();
expect(actions.f1).toBeCalled();
});
但是测试失败,表明没有调用模拟函数。我也尝试过交换测试的第二行和第三行,但无济于事。
我的笑话配置都很好,实际上我一直在进行其他一系列有效的测试(在同一文件中)。
我在这里想念什么?
注意:此操作的实际实现(在此我将对其进行简化)涉及一个actions
文件,该文件包含一个公用export function fetchStations()
,该公用export function _downloadStations()
调用了一个私有的(或未导出的){{ 1}}。我正在尝试测试是否调用了_downloadStations()
。
我仅为方便起见使用import * as actions
,所以我可以写那行,然后使用文件在actions.whatever()
下导出的任何函数(而不是在我决定时必须将函数添加到import语句中)使用它们)。如果我没有注意到import * as actions
有什么作用(如下面的brian所暗示),那么我当然不必使用它,当然可以使用import {thisAction, thatAction} from './actions'
。
答案 0 :(得分:1)
此行:
import * as actions from './actions.js'
将模块导出从actions.js
绑定到actions
...
...因此将actions.f1
设置为模拟函数将替换f1
的模块导出 ...
...但是这不会影响calls_f1
,因为它会直接调用f1
。
如果将calls_f1
更改为为f1
调用 module export ,则它将调用模拟函数。
有两种方法可以实现这一目标。
一种方法是将f1
移到其自己的模块中。
另一种方法是注意ES6模块"support cyclic dependencies automatically"(ES6模块的主要设计目标),以便模块可以导入自己的导出文件:
actions.js
import * as actions from './actions'; // <= import the module...
export function f1() {
return 1
}
export function calls_f1() {
actions.f1() // <= ...and use it to call f1
}
actions.test.js
import * as actions from './actions.js'
describe('actions', () => {
it('calls_f1 should call f1', () => {
actions.f1 = jest.fn();
actions.calls_f1();
expect(actions.f1).toBeCalled(); // Success!
})
})
更新
OP更新了问题,以指示相关功能未从模块中导出。
在这种情况下,这只是模块的内部实现细节,不能直接被窥探。
测试它会涉及测试它引起的效果,而不是直接监视它是否被调用。