React Native: Jest模拟平台

3
当为React Native项目编写单元测试时,我希望能够基于不同平台测试不同的快照。我首先尝试使用jest.mock来模拟Platform,但似乎是异步的。当我有两个单独的文件时,这种方法确实有效,但如果可能的话,我更喜欢将所有内容都放在一个文件中。我尝试了jest.doMock,因为文档中有以下片段:

使用babel-jest时,对mock的调用将自动提升到代码块的顶部。如果要明确避免此行为,请使用此方法。 https://facebook.github.io/jest/docs/en/jest-object.html#jestdomockmodulename-factory-options

然而,我仍然看到不期望的结果。当我在android测试中使用console.log时,我看到Platform.OS是我设置的第一个doMock的值。
我还尝试将模拟对象包装在beforeEach中的describe中,因为我认为这可能有助于作用域。 http://facebook.github.io/jest/docs/en/setup-teardown.html#scoping
 describe('ios test', () => {
  it('renders ui correctly', () => {
    jest.doMock('Platform', () => {
      const Platform = require.requireActual('Platform');
      Platform.OS = 'ios';
      return Platform;
    });
    const wrapper = shallow(<SomeComponent />);
    const tree = renderer.create(wrapper).toJSON();
    expect(tree).toMatchSnapshot();
  });
});

describe('android test', () => {
  it('renders ui correctly', () => {
    jest.doMock('Platform', () => {
      const Platform = require.requireActual('Platform');
      Platform.OS = 'android';
      return Platform;
    });
    const wrapper = shallow(<SomeComponent />);
    const tree = renderer.create(wrapper).toJSON();
    expect(tree).toMatchSnapshot();
  });
});

有什么想法可以在同一文件中更改测试的模拟平台吗?

有人在使用流程时遇到问题:请使用jest.requireActual而不是require.requireActual - David Schumann
1个回答

5

另一个问题中,有很多关于如何解决这个问题的建议,但是对于我来说,没有一个建议成功,因为你需要在同一个测试套件文件和一个测试运行中针对不同操作系统进行测试。

最终,我通过编写一个有些笨拙的辅助函数进行了解决,该函数可以像预期的那样在测试中进行模拟,例如:

export function getOS() {
  return Platform.OS;
}

在您的代码中使用它来代替Platform.OS,然后在测试中简单地模拟它,例如:

it('does something on Android', () => {
  helpers.getOS = jest.fn().mockImplementationOnce(() => 'android');
  // ...
}

成功了,感谢这位提供的建议。


1
即使在2021年,我认为这是这个问题的最佳答案和最佳选择。 - Carlos Querioz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接