Jest – 如何模拟模块的非默认导出?

Gui*_*tti 6 unit-testing mocking jestjs react-native

我正在尝试NativeModules从进行模拟react-native,但我找不到只模拟该类而不是整个react-native模块的方法。

基本上,在我的生产代码中,我这样做:

import { NativeModules } from 'react-native'
const { MyCustomNativeModule } = NativeModules
Run Code Online (Sandbox Code Playgroud)

在我的测试中,我想重写MyCustomNativeModule. 目前我发现的唯一方法是react-native像这样模拟整个模块:

// /__mocks__/react-native.js

module.exports = {
  NativeModules: {
    MyCustomNativeModule: {
      dismiss: () => {},
    },
  },
}
Run Code Online (Sandbox Code Playgroud)

但这破坏了所有其他react-native功能。我看到人们经常使用类似的方法,jest.mock('NativeModules', () => ... )但这似乎并不奏效!

sli*_*wp2 5

jest.mock这是使用手动模拟模块的解决方案react-native

\n\n

为了简单起见,我模拟了react-native模块。可以用真实的react-native代替模拟的。

\n\n

文件结构为:

\n\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 index.spec.ts\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 index.ts\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 react-native.ts\n
Run Code Online (Sandbox Code Playgroud)\n\n

模拟react-native模块:

\n\n

react-native.ts:

\n\n
const NativeModules = {\n  MyCustomNativeModule: {\n    dismiss: () => {\n      // original implementation\n      return \'real data\';\n    }\n  }\n};\n\nexport { NativeModules };\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

index.ts,假设您react-native在此文件中导入并使用模块:

\n\n
import { NativeModules } from \'./react-native\';\n\nexport function main() {\n  return NativeModules.MyCustomNativeModule.dismiss();\n}\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

单元测试,index.spec.ts

\n\n
import { main } from \'./\';\nimport { NativeModules } from \'./react-native\';\n\njest.mock(\'./react-native\', () => {\n  return {\n    NativeModules: {\n      MyCustomNativeModule: {\n        dismiss: jest.fn()\n      }\n    }\n  };\n});\n\ndescribe(\'main\', () => {\n  it(\'should mock react-native correctly\', () => {\n    const mockedData = \'mocked data\';\n    (NativeModules.MyCustomNativeModule.dismiss as jest.MockedFunction<\n      typeof NativeModules.MyCustomNativeModule.dismiss\n    >).mockReturnValueOnce(mockedData);\n\n    const actualValue = main();\n    expect(actualValue).toBe(mockedData);\n    expect(NativeModules.MyCustomNativeModule.dismiss).toBeCalledTimes(1);\n  });\n});\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

100%覆盖率的单元测试结果:

\n\n
 PASS  src/stackoverflow/54393006/index.spec.ts\n  main\n    \xe2\x9c\x93 should mock react-native correctly (19ms)\n\n----------|----------|----------|----------|----------|-------------------|\nFile      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |\n----------|----------|----------|----------|----------|-------------------|\nAll files |      100 |      100 |      100 |      100 |                   |\n index.ts |      100 |      100 |      100 |      100 |                   |\n----------|----------|----------|----------|----------|-------------------|\nTest Suites: 1 passed, 1 total\nTests:       1 passed, 1 total\nSnapshots:   0 total\nTime:        5.096s\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是完成的演示:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/54393006

\n


Def*_*ian -2

这个怎么样: https: //jestjs.io/docs/en/es6-class-mocks

班级

// sound-player.js
 export default class SoundPlayer {
   constructor() {
    this.foo = 'bar';
 }

  playSoundFile(fileName) {
   console.log('Playing sound file ' + fileName);
 }
}
Run Code Online (Sandbox Code Playgroud)

使用 jest.mock( ) 进行嘲笑

import SoundPlayer from './sound-player';
const mockPlaySoundFile = jest.fn();
jest.mock('./sound-player', () => {
   return jest.fn().mockImplementation(() => {
       return {playSoundFile: mockPlaySoundFile};
    });
  });
Run Code Online (Sandbox Code Playgroud)

更新

这种方式怎么样:

function mockFunctions() {
  const original = require.requireActual('../myModule');
  return {
    ...original, //Pass down all the exported objects
    test: jest.fn(() => {console.log('I didnt call the original')}),
    someFnIWantToCurry: {console.log('I will curry the original') return jest.fn((...args) => original.someFnIWantToCurry(...args)}),
  }
jest.mock('../myModule', () => mockFunctions());
const storage = require.requireMock('../myModule');
Run Code Online (Sandbox Code Playgroud)

请参阅:https ://github.com/facebook/jest/issues/936#issuecomment-265074320