如何更改某个测试的Jest模拟的实现

时间:2018-09-04 19:02:50

标签: javascript typescript react-native jestjs

我已经在我的test/__mocks__文件夹中创建了一个模拟npm模块的文件。而且此文件的链接已添加到我的笑话设置中。所有的工作都很好,这让我很好地进行了测试。但是现在对于某种测试,我需要更改此测试的返回值。我该如何实现?

我尝试取消模拟以及setMock等。但是没有任何效果。

// test/__mocks__/touchId.ts

jest.mock('react-native-touch-id', () => {
  return {
    isSupported: jest.fn(() => Promise.resolve(true)),
    authenticate: jest.fn(() => Promise.resolve(true)),
  };
});

我的考试

it('should not navigate to main if touch id return false', async () => {
  jest.setMock('react-native-touch-id', {
    authenticate: jest.fn(() => Promise.resolve(false)),
  });
  const pinCreation = new PinCreationStore();

  const spy = jest.spyOn(NavigationServices, 'navigate');

  spy.mockReset();

  await pinCreation.verifyUser();

  expect(spy).toHaveBeenCalledTimes(0);

  spy.mockRestore();
});

这里我仍然是真实的,所以我的测试崩溃了。

1 个答案:

答案 0 :(得分:0)

您可以使用jest.mock()而不创建__mocks__文件夹。

例如:

react-native-touch-id.ts,为了简化它,我模拟了此模块。您可以将其替换为实际的npm模块。

const touchId = {
  isSupported() {
    return false;
  },
  authenticate() {
    return false;
  }
};
export default touchId;

react-native-touch-id.spec.ts

import touchId from './react-native-touch-id';

jest.mock('./react-native-touch-id', () => {
  return {
    isSupported: jest.fn(() => Promise.resolve(true)),
    authenticate: jest.fn(() => Promise.resolve(true))
  };
});

describe('react-native-touch-id', () => {
  it('t1', () => {
    expect(touchId.isSupported()).toBeTruthy();
    expect(touchId.authenticate()).toBeTruthy();
  });

  it('t2', () => {
    (touchId.isSupported as jest.MockedFunction<typeof touchId.isSupported>).mockReturnValueOnce(false);
    (touchId.authenticate as jest.MockedFunction<typeof touchId.authenticate>).mockReturnValueOnce(false);
    expect(touchId.isSupported()).toBeFalsy();
    expect(touchId.authenticate()).toBeFalsy();
  });

  it('t3', () => {
    (touchId.isSupported as jest.MockedFunction<typeof touchId.isSupported>).mockReturnValueOnce(true);
    (touchId.authenticate as jest.MockedFunction<typeof touchId.authenticate>).mockReturnValueOnce(false);
    expect(touchId.isSupported()).toBeTruthy();
    expect(touchId.authenticate()).toBeFalsy();
  });
});

如您所见,在模拟react-native-touch-id模块之后,当您希望这两个方法具有不同的值时,需要将其导入并再次模拟。这些模拟值将在导入和使用isSupported模块的authenticatereact-native-touch-id方法的其他模块中使用。

单元测试结果:

 PASS  src/stackoverflow/52172531/react-native-touch-id.spec.ts
  react-native-touch-id
    ✓ t1 (5ms)
    ✓ t2 (1ms)
    ✓ t3

Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        4.065s