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

Javascript Jest:如何正确模拟节点模块?,javascript,reactjs,unit-testing,react-native,jestjs,Javascript,Reactjs,Unit Testing,React Native,Jestjs,我想在React Native with Jest中模拟节点_模块“React Native Keychain” 接下来,我创建了一个名为\uuuumocks\uuuu的文件夹,并在其中创建了一个名为react native keychain.js的文件 以下是文件中的代码: export default jest.mock("react-native-keychain", () => { const token = "abcdefghijklmnopqrstuvwxyz0123456

我想在React Native with Jest中模拟节点_模块“React Native Keychain”

接下来,我创建了一个名为
\uuuumocks\uuuu
的文件夹,并在其中创建了一个名为
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)
这告诉我: 1.mock可以工作(因为正确返回true),或者调用React Native Keychain中的实际
setGenericPassword
函数。 2.出于某种原因,
keychainfunctions
被定义为
jest.mock
对象,而不是三个模拟函数

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

在注释中建议仅导出对象。这种变通方法有效。我仍然对如何正确做/我做错了什么感兴趣

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
您可以尝试在测试中使用并仅模拟您需要的方法。(以前在26之前的笑话版本中称为genMockFromModule)


希望这有帮助

Bamse不喜欢嘲笑,但无论如何都有帮助。Lycklig den som har en sådan vän.:-)我认为如果在
\uuuu mocks\uuuu/react native keychain.js
中使用所需的方法导出对象,您的模拟也会起作用。当前您正在导出一个
jest
mock。Visibleman今天早上你让我笑了,让我想起了我以前的漫画书。我试着这样使用它:
const keyChainFunctions=jest.genMockFromModule(“react native keychain”).default但它也抛出了相同的错误。您是正确的。仅导出普通对象即可。我在问题中添加了它。这个答案可能也很有用:如果您只需要一个返回值,您可以简单地使用
jest.mock(module)创建模块
从“模块”导入模块
module.mockReturnValue(Promise.resolve('response')
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