繁体   English   中英

Jest:如何正确模拟节点模块?

Jest: How to correctly mock a node module?

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

我想用 Jest 模拟 React Native 中的 node_module 'React Native Keychain'。

按照文档,我创建了一个名为__mocks__的文件夹,并在其中创建了一个名为react-native-keychain.js的文件。

这是文件中的代码:

export default jest.mock("react-native-keychain", () => {
  const token = "abcdefghijklmnopqrstuvwxyz0123456789";
  const credentials = {
    username: "session",
    password: token
  };
  return {
    setGenericPassword: jest.fn(
      (username, password) => new Promise((resolve, reject) => resolve(true)) // eslint-disable-line no-unused-vars
    ),
    getGenericPassword: jest.fn(() => new Promise((resolve, reject) => resolve(credentials))), // eslint-disable-line no-unused-vars
    resetGenericPassword: jest.fn(() => new Promise((resolve, reject) => resolve(true))) // eslint-disable-line no-unused-vars
  };
});

然后我为使用这个库的函数编写了我的测试:

import * as keyChainFunctions from "react-native-keychain";
import { setToken, getToken, clearToken } from "./secureStorage";

const token = "abcdefghijklmnopqrstuvwxyz0123456789";

    describe("set token", () => {
      it("saves the token in the keychain", () => {
        expect.assertions(1);
        return setToken(token).then(res => {
          console.log(res);
          console.log(keyChainFunctions);
          expect(keyChainFunctions.setGenericPassword).toHaveBeenCalledWith("session", token);
        });
      });
    });

问题是,测试失败。 我收到错误消息:

 FAIL  app/api/secureStorage/secureStorage.test.js
  set token
    ✕ saves the token in the keychain (42ms)

  ● set token › saves the token in the keychain

    expect(jest.fn())[.not].toHaveBeenCalledWith()

    jest.fn() value must be a mock function or spy.
    Received: undefined

      10 |       console.log(res);
      11 |       console.log(keyChainFunctions);
    > 12 |       expect(keyChainFunctions.setGenericPassword).toHaveBeenCalledWith("session", token);
         |                                                    ^
      13 |     });
      14 |   });
      15 | });

      at app/api/secureStorage/secureStorage.test.js:12:52
      at tryCallOne (node_modules/promise/lib/core.js:37:12)
      at node_modules/promise/lib/core.js:123:15
      at flush (node_modules/asap/raw.js:50:29)
 ● set token › saves the token in the keychain

    expect.assertions(1)

    Expected one assertion to be called but received zero assertion calls.

       6 | describe("set token", () => {
       7 |   it("saves the token in the keychain", () => {
    >  8 |     expect.assertions(1);
         |            ^
       9 |     return setToken(token).then(res => {
      10 |       console.log(res);
      11 |       console.log(keyChainFunctions);

      at Object.<anonymous> (app/api/secureStorage/secureStorage.test.js:8:12)

console.log()产量:

console.log app/api/secureStorage/secureStorage.test.js:10
    true

  console.log app/api/secureStorage/secureStorage.test.js:11
    { default:
       { addMatchers: [Function: addMatchers],

         advanceTimersByTime: [Function: advanceTimersByTime],
         autoMockOff: [Function: disableAutomock],
         autoMockOn: [Function: enableAutomock],
         clearAllMocks: [Function: clearAllMocks],
         clearAllTimers: [Function: clearAllTimers],
         deepUnmock: [Function: deepUnmock],
         disableAutomock: [Function: disableAutomock],
         doMock: [Function: mock],
         dontMock: [Function: unmock],
         enableAutomock: [Function: enableAutomock],
         fn: [Function: bound fn],
         genMockFromModule: [Function: genMockFromModule],
         isMockFunction: [Function: isMockFunction],
         mock: [Function: mock],
         requireActual: [Function: bound requireModule],
         requireMock: [Function: bound requireMock],
         resetAllMocks: [Function: resetAllMocks],
         resetModuleRegistry: [Function: resetModules],
         resetModules: [Function: resetModules],
         restoreAllMocks: [Function: restoreAllMocks],
         retryTimes: [Function: retryTimes],
         runAllImmediates: [Function: runAllImmediates],
         runAllTicks: [Function: runAllTicks],
         runAllTimers: [Function: runAllTimers],
         runOnlyPendingTimers: [Function: runOnlyPendingTimers],
         runTimersToTime: [Function: runTimersToTime],
         setMock: [Function: setMock],
         setTimeout: [Function: setTimeout],
         spyOn: [Function: bound spyOn],
         unmock: [Function: unmock],
         useFakeTimers: [Function: useFakeTimers],
         useRealTimers: [Function: useRealTimers] } }

这告诉我什么: 1. 模拟工作(因为 true 正确返回)或来自 React Native Keychain 的实际setGenericPassword函数正在被调用。 2. 出于某种原因, keychainfunctions被定义,但作为jest.mock对象而不是三个jest.mock函数。

如果模拟有效,感觉 1 和 2 相互矛盾。 我究竟做错了什么? 为什么这个模拟不起作用? 如何解释这些奇怪的console.log()和失败的测试?

Bamse在评论中建议只导出对象。 此解决方法有效。 我仍然会对如何正确做/我做错了什么感兴趣。

const token = "abcdefghijklmnopqrstuvwxyz0123456789";
const credentials = {
  username: "session",
  password: token
};

export const setGenericPassword = jest.fn(
  (username, password) => new Promise((resolve, reject) => resolve(true)) // eslint-disable-line no-unused-vars
);

export const getGenericPassword = jest.fn(
  () => new Promise((resolve, reject) => resolve(credentials)) // eslint-disable-line no-unused-vars
);

export const resetGenericPassword = jest.fn(() => new Promise((resolve, reject) => resolve(true))); // eslint-disable-line no-unused-vars
1 个回复

您可以尝试在测试中使用jest.createMockFromModule并仅模拟您需要的方法。 (以前在 26 之前的 Jest 版本中称为 genMockFromModule)

希望能帮助到你

1 用Jest和@ std / esm模拟节点模块

我目前在为使用@std/esm的节点应用程序编写测试时遇到问题。 我已经在__mocks__目录中设置了一个节点模块的手动模拟,以下代码显示了使用该模拟节点模块的文件测试。 (在db.mjs中使用) 但是,当我运行Jest时,没有使用手动模拟,而是使用了真正的节点模块。 是否有 ...

2 如何在 Jest 中正确模拟类模块?

我正在使用这个amplitude模块,它要求我先实例化一个类,然后使用实例方法。 代码如下: 然后我稍后调用await amplitude.track({something: 'here'})并想要模拟它,以便不调用外部库并且我可以验证参数。 我必须初始化一个类的事实让我厌烦了模拟。 我尝试使 ...

4 用Jest模拟模块变量

我一直在使用Jest来模拟一些变量,这些变量用在经过测试的函数中,如下所示: 在这里, SERVER_URL的新设置值由hydrateApp() 。 但是,我不能使用module来做到这一点。 当我尝试设置module.hot时,在调用该函数时它将仍然是未定义的: 在这种情况 ...

6 Mocking 一个带有 Jest 的 NodeJS 模块

我花了一整天的时间寻找这个。 我有以下代码。 在我的测试中,我想模拟CarModel或CarService 。 要么对我有用。 我模拟这些的原因是用内存数据库替换真实数据库。 但我找不到任何可行的解决方案。 如果你们中的任何人有任何想法,那么我将不胜感激。 ###编辑### 汽车服务.js ...

8 用Jest部分模拟React模块

我试图在导入的React模块中仅模拟一个功能,保持模块的其余部分不变,并在所有测试的顶层执行此操作。 我正在使用带有单个测试的新鲜create-react-app项目来观察问题。 重现步骤: create-react-app test 使用提供的src/App.te ...

9 Mocking Jest 中的一个导入模块

我试图弄清楚如何在我的测试文件中用 Jest 模拟一个常量( DEFAuLT_OPTIONS ) 我有以下文件结构: 文件 我怎样才能 - 模拟单个测试的DEFAULT_OPTIONS值? 为一组测试模拟DEFAULT_OPTIONS的值? (如果不同) 谢谢! 编辑:我尝试了以下但模块似乎有一个 ...

10 Jest - 模拟 `config` 模块

我正在编写一个单元测试,我想模拟调用config时返回的值。 在模块中,我多次调用 config,并希望模拟其中一个调用的返回值: 例如,我如何模拟config.get('AWS_DYNAMODB_CLIENT_TIMEOUT')的返回值。 请指教。 ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2022 STACKOOM.COM