来自 gobal 模块的笑话模拟常量

Mat*_*ain 1 mocking jestjs expo

我正在玩 Jest,并努力弄清楚如何模拟一个对象。我看到的大多数示例都展示了如何模拟函数。

这是我的组件AboutScreen.js

import React from 'react';
import { Constants, WebBrowser } from 'expo';
import { View, Text } from 'react-native';
import config from '../config';

const AboutScreen = () => {
const { termsAndConditionsUrl, privacyPolicyUrl } = config;
const { releaseChannel, version } = Constants.manifest;
const channel = (releaseChannel === undefined) ? 'DEV' : releaseChannel;
return (
    <View>
        <Text>Version: {version}, Release-channel: {channel}</Text>
        <Text testId={"t-and-c"} onPress={() => WebBrowser.openBrowserAsync(termsAndConditionsUrl)}>
    Terms & conditions
        </Text>
    </View>
  );
};


export default AboutScreen;
Run Code Online (Sandbox Code Playgroud)

我的测试AboutScreen.test.js如下所示

 import React from 'react';
 import { shallow } from 'enzyme';
 import config from '../../config';
 import AboutScreen from '../AboutScreen';
 import { Constants, WebBrowser } from 'expo';
 const { termsAndConditionsUrl, privacyPolicyUrl } = config;

  jest.mock('expo', () => ({
   Constants:{
     manifest: {
       version: '0.0.1',
       releaseChannel: 'PROD',
    }},
  }));

  it('renders with releaseChannel and version', () => {
    const wrapper = shallow(<AboutScreen />);
    expect(wrapper).toMatchSnapshot();
    expect(wrapper).toContain('PROD');
    expect(wrapper).toContain('0.0.1');
  });

  jest.mock('expo', () => ({
   Constants:{
     manifest: {
       version: '0.0.2',
    }},
  }));

  it('renders with default releaseChannel', () => {
    const wrapper = shallow(<AboutScreen />);
    expect(wrapper).toMatchSnapshot();
    expect(wrapper).toContain('DEV');
    expect(wrapper).toContain('0.0.2');
   });
Run Code Online (Sandbox Code Playgroud)

对于第一个测试,包装器应包含“PROD”且版本为“0.0.1”。

但对于第二个测试,包装器应包含默认值“DEV”。

第二个测试似乎一直失败,因为模拟没有覆盖。

我尝试了其他选项,例如

jest.mock('expo');
import * as expo from 'expo';
expo.mockReturnValueOnce(); //but fails here as expo has no mockReturnValueOnce
Run Code Online (Sandbox Code Playgroud)

我该如何解决这个问题?

Bri*_*ams 5

\n\n

以下是来自Exploring ES6的一个实用技巧:

\n\n
\n

请注意,虽然您无法更改导入的值,但您可以更改它们所引用的对象。

\n
\n\n

因此,如果您导入了某些内容,则不能只是将其分配给其他内容...但如果它引用一个对象,那么您可以更改该对象

\n\n
\n\n

在此测试jest.mock中将进行模拟expo,并使import { Constants } from \'expo\';您可以访问模拟Constants对象...

\n\n

...然后你可以更改该对象

\n\n
import React from \'react\';\nimport { shallow } from \'enzyme\';\nimport config from \'../../config\';\nimport AboutScreen from \'../AboutScreen\';\nimport { Constants, WebBrowser } from \'expo\';\nconst { termsAndConditionsUrl, privacyPolicyUrl } = config;\n\njest.mock(\'expo\', () => ({\n  Constants: {\n    manifest: {\n      version: \'0.0.1\',\n      releaseChannel: \'PROD\',\n    }\n  },\n}));\n\nit(\'renders with releaseChannel and version\', () => {\n  const wrapper = shallow(<AboutScreen />);\n  expect(wrapper).toMatchSnapshot();  // Success!\n  expect(wrapper.contains(\'PROD\')).toBe(true);  // Success!\n  expect(wrapper.contains(\'0.0.1\')).toBe(true);  // Success!\n});\n\nit(\'renders with default releaseChannel\', () => {\n  Constants.manifest = {\n    version: \'0.0.2\'\n  };  // change the manifest property of Constants\n  const wrapper = shallow(<AboutScreen />);\n  expect(wrapper).toMatchSnapshot();  // Success!\n  expect(wrapper.contains(\'DEV\')).toBe(true);  // Success!\n  expect(wrapper.contains(\'0.0.2\')).toBe(true);  // Success!\n});\n
Run Code Online (Sandbox Code Playgroud)\n