开玩笑–如何模拟模块的非默认导出?

时间:2019-01-27 21:24:06

标签: unit-testing react-native mocking jestjs

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

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

import { NativeModules } from 'react-native'
const { MyCustomNativeModule } = NativeModules

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

// /__mocks__/react-native.js

module.exports = {
  NativeModules: {
    MyCustomNativeModule: {
      dismiss: () => {},
    },
  },
}

但这破坏了所有其他react-native函数。我看到人们经常使用joy.mock('NativeModules', () => ... )之类的方法,但实际上似乎不起作用!

2 个答案:

答案 0 :(得分:0)

这是怎么回事: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);
 }
}

模拟jest.mock()

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

更新

这种方式如何:

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');

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

答案 1 :(得分:0)

这是使用dis.dis(add)手动模拟jest.mock模块的解决方案。

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

文件结构为:

react-native

模拟的. ├── index.spec.ts ├── index.ts └── react-native.ts 模块:

react-native

react-native.ts

const NativeModules = { MyCustomNativeModule: { dismiss: () => { // original implementation return 'real data'; } } }; export { NativeModules }; ,假设您导入并使用此文件中的index.ts模块:

react-native

单元测试import { NativeModules } from './react-native'; export function main() { return NativeModules.MyCustomNativeModule.dismiss(); }

index.spec.ts

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

import { main } from './';
import { NativeModules } from './react-native';

jest.mock('./react-native', () => {
  return {
    NativeModules: {
      MyCustomNativeModule: {
        dismiss: jest.fn()
      }
    }
  };
});

describe('main', () => {
  it('should mock react-native correctly', () => {
    const mockedData = 'mocked data';
    (NativeModules.MyCustomNativeModule.dismiss as jest.MockedFunction<
      typeof NativeModules.MyCustomNativeModule.dismiss
    >).mockReturnValueOnce(mockedData);

    const actualValue = main();
    expect(actualValue).toBe(mockedData);
    expect(NativeModules.MyCustomNativeModule.dismiss).toBeCalledTimes(1);
  });
});

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