React Native如何在1个特定测试中模拟PixelRatio

时间:2017-09-07 09:27:23

标签: reactjs unit-testing react-native jestjs

我在使用react-native测试我的快照时遇到了问题,更具体地说,我遇到了麻烦的PixelRatio。

代码说的不仅仅是文字 - 我已经简化了代码并删除了所有的噪音:

组件:

const Slide = (props) => (
  <Image
    source={props.source}
        style={PixelRatio.get() === 2 ?
            { backgroundColor: 'red' } :
            { backgroundCoor: 'green' }}
  />
);

快照测试

import { Platform } from 'react-native';
describe('When loading the Slide component', () => {
  it('should render correctly on ios', () => {
    Platform.OS = 'ios';
    const tree = renderer.create(
      <Provider store={store}>
        <Slide />
      </Provider>,
    ).toJSON();
    expect(tree).toMatchSnapshot();
  });

  describe('on devices with a pixelRatio of 2', () => {
    it('it should render correctly', () => {
      jest.mock('PixelRatio', () => ({
        get: () => 2,
        roundToNearestPixel: jest.fn(),
      }));

      const tree = renderer.create(
        <Provider store={store}>
          <Slide />
        </Provider>,
      ).toJSON();
      expect(tree).toMatchSnapshot();
    });
  });
});

但是这不起作用,经过一些挖掘后我发现bug on github已经解决了 - 显然你需要使用beforeEach。但这似乎也没有奏效,或者我做错了?

使用建议的github解决方案进行快照测试

import { Platform } from 'react-native';
describe('When loading the Slide component', () => {
  it('should render correctly on ios', () => {
    Platform.OS = 'ios';
    const tree = renderer.create(
      <Provider store={store}>
        <Slide />
      </Provider>,
    ).toJSON();
    expect(tree).toMatchSnapshot();
  });

  describe('on devices with a pixelRatio of 2', () => {
    it('it should render correctly', () => {
      beforeEach(() => {
        jest.mock(pxlr, () => ({
          get: () => 2,
          roundToNearestPixel: jest.fn(),
        }));
        const pxlr = require('react-native').PixelRatio;
      }

      const tree = renderer.create(
        <Provider store={store}>
          <Slide />
        </Provider>,
      ).toJSON();
      expect(tree).toMatchSnapshot();
    });
  });
});

1 个答案:

答案 0 :(得分:2)

当你写jest.mock('my-module', () => {...})时,你告诉jest模拟名为'my-module'的模块。然后当你写const MyModule = require('my-module')时,你会得到一个模拟。

如果jest.mock('PixelRatio', () => {...})是一个模块,那么声明PixelRatio会有意义,但它不是。 PixelRatio是一个全局JS变量(准确地说是JS class)。您可以按如下方式模拟其静态方法:

1)使用jest.spyOn方法:

const mockGet = jest.spyOn(PixelRatio, 'get')
  .mockImplementation(() => customImplementation)
const mockRoundToNearestPixel = jest.spyOn(PixelRatio, 'roundToNearestPixel')
  .mockImplementation(() => customImplementation)

2)使用jest.fn方法:

PixelRatio.get = jest.fn(() => customImplementation)
PixelRatio.roundToNearestPixel = jest.fn(() => customImplementation)