首页 > 解决方案 > 永远不会调用带有 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()

测试代码执行以下操作:

  1. 添加 invalidLOGIN_START_SECRET以便实际代码在进入第一个catch.
  2. 为事件订阅事件处理程序WELCOME_MESSAGE_RENDERED
  3. 模拟store.addTerminalItem模块功能。
  4. 发布事件以触发上述async handle()函数。
  5. 检查是否调用了模拟函数。

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

以下是我们迄今为止尝试过的以下事情:

如果有人可以在这里给我们任何指示,将不胜感激。

标签: javascriptjestjs

解决方案


没有手头的代码很难确定,但请尝试使用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)
})

推荐阅读