嘲笑没有被嘲笑

时间:2019-05-08 16:44:33

标签: unit-testing jestjs

请帮助我了解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'

1 个答案:

答案 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更新了问题,以指示相关功能未从模块中导出。

在这种情况下,这只是模块的内部实现细节,不能直接被窥探。

测试它会涉及测试它引起的效果,而不是直接监视它是否被调用。