【问题标题】:How do change implementation of a Jest mock for a certain test如何为某个测试更改 Jest 模拟的实现
【发布时间】:2019-02-09 20:31:56
【问题描述】:

我在我的 test/__mocks__ 文件夹中创建了一个文件,我在其中模拟了一个 npm 模块。这个文件的链接被添加到我的笑话设置中。一切都很好,这让我可以很好地测试它。但是现在对于某个测试,我需要更改此测试的返回值。我怎样才能做到这一点?

我尝试 unMock 加上 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();
});

在这里我仍然正确,所以我的测试崩溃了。

【问题讨论】:

    标签: javascript typescript react-native jestjs


    【解决方案1】:

    您可以在不创建__mocks__ 文件夹的情况下使用jest.mock()

    例如:

    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 模块后,当您希望这两个方法具有不同的值时,您需要将其导入并再次模拟。这些模拟值将用于导入和使用react-native-touch-id 模块的isSupportedauthenticate 方法的其他模块。

    单元测试结果:

     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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-25
      • 2019-12-20
      • 1970-01-01
      • 1970-01-01
      • 2017-11-07
      • 2020-01-05
      • 2021-09-22
      相关资源
      最近更新 更多