javascript - 永远不会调用带有 Jest 的模拟模块函数
问题描述
我有一个非常奇怪的情况,我的 Jest 测试通过了我的 Windows 10 桌面和 Macbook Pro,但它们没有通过我其他朋友的两个 Windows 10 桌面。
正在测试的代码
import { addTerminalItem } from '../../store'
...
class LoginUser extends EventHandler {
...
async handle () {
if (this.isFromOauthRedirect) {
try {
await this._handleOauthRedirect()
} catch (e) {
addTerminalItem(new ErrorMessage(e.message))
}
return
}
if (await zaClient.isUserLoggedIn('testUserId')) {
// TODO: user is already logged in, do something
} else {
const loginStartSecret = uuidv4()
localStorage.setItem(LOGIN_START_SECRET, loginStartSecret)
addTerminalItem(new LoginMessage(loginStartSecret))
}
}
...
}
export const loginUser = new LoginUser()
测试代码执行以下操作:
- 添加 invalid
LOGIN_START_SECRET
以便实际代码在进入第一个catch
. - 为事件订阅事件处理程序
WELCOME_MESSAGE_RENDERED
。 - 模拟
store.addTerminalItem
模块功能。 - 发布事件以触发上述
async handle()
函数。 - 检查是否调用了模拟函数。
import * as store from '../../../store'
...
test('different login start secret in localstorage', async () => {
localStorage.setItem(LOGIN_START_SECRET, 'different-secret')
zaClient.login = jest.fn(() => true)
store.addTerminalItem = jest.fn()
await pubsub.publish(WELCOME_MESSAGE_RENDERED)
expect(store.addTerminalItem).toHaveBeenCalledWith(expect.any(ErrorMessage))
const errorMessage = store.addTerminalItem.mock.calls[0][0]
expect(errorMessage.message).toBe(loginSecurityErrorMsg)
})
正如我在我的电脑上所说的,它正确地显示addTerminalItem
了在我家里的两台机器上使用正确的参数调用了一次函数。然而,这个模拟函数永远不会在我朋友的两台机器上被调用并且失败。他们得到的实际错误信息如下:
expect(jest.fn()).toHaveBeenCalledWith(...expected)
Expected: Any<ErrorMessage>
Number of calls: 0
以下是我们迄今为止尝试过的以下事情:
- 新鲜
git clone
的yarn install
, 和yarn test
. 我通过了,他们没有。 - 通过
addTerminalItem
模拟,我们添加了一个console.log
内部addTerminalItem
,它没有正确记录,但仍然是 0 次调用。 - 通过
addTerminalItem
spyed,我们添加了一个console.log
内部addTerminalItem
并且它正确记录了,但仍然是 0 次调用(这对我来说没有意义) - 我们匹配了我们的纱线版本。
- 我们仔细调试了代码,以确保所有其他事情都按预期工作。
如果有人可以在这里给我们任何指示,将不胜感激。
解决方案
没有手头的代码很难确定,但请尝试使用jest.mock
:
import {addTerminalItem} from "../../../store";
jest.mock('../../../store', () => ({
addTerminalItem: jest.fn()
));
//... stuff ...
test('different login start secret in localstorage', async () => {
localStorage.setItem(LOGIN_START_SECRET, 'different-secret')
zaClient.login = jest.fn(() => true)
await pubsub.publish(WELCOME_MESSAGE_RENDERED)
expect(addTerminalItem).toHaveBeenCalledWith(expect.any(ErrorMessage))
const errorMessage = addTerminalItem.mock.calls[0][0]
expect(errorMessage.message).toBe(loginSecurityErrorMsg)
})