react-native - 开玩笑地模拟和监视导入的异步函数
问题描述
我想弄清楚如何在 Jest 中模拟导入的属性函数
这是我的组件AboutScreen.js
import React from 'react';
import { Constants, WebBrowser } from 'expo';
import { View, Text } from 'react-native';
const AboutScreen = () => {
return (
<View>
<Text testId={"t-and-c"} onPress={() => WebBrowser.openBrowserAsync('tcUrl')}>
Terms & conditions
</Text>
</View>
);
};
export default AboutScreen;
我在 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',
},
WebBrowser: {
openBrowserAsync: jest.fn()
}
},
}));
it('click on terms and conditions link', () => {
const mock = jest.spyOn(WebBrowser, 'openBrowserAsync');
mock.mockImplementation(() => Promise.resolve());
// above statement return 'Cannot spyOn on a primitive value; undefined given'
// WebBrowser.openBrowserAsync = jest.fn(); --> This returns `WebBroser undefined
const wrapper = shallow(<AboutScreen />);
wrapper.find({ testId: 't-and-c' }).simulate('click');
expect(mock).lastCalledWith('abc');
// expect(WebBrowser.openBrowserAsync).toHaveBeenCalledWith('tcUrl);
});
我能够模拟Constants.manifest.version
但无法弄清楚如何模拟“浏览器”对象中的函数。
解决方案
你很近。
您当前正在模拟WebBrowser
成为内部的属性Constants
,因此需要像这样将其移出:
jest.mock('expo', () => ({
Constants: {
manifest: {
version: '0.0.1',
releaseChannel: 'PROD',
}
},
WebBrowser: {
openBrowserAsync: jest.fn()
}
}));
另一个问题是simulate
使用shallow
. 从文档的Common Gotchas部分:
尽管名称暗示这模拟了一个实际事件,但
.simulate()
实际上会根据你给它的事件来定位组件的道具。例如,.simulate('click')
将实际获取onClick
道具并调用它。
...并且由于您的组件没有onClick
属性调用.simulate('click')
最终什么都不做。
来自 Airbnb 开发人员的这篇文章建议直接调用 props 并避免simulate
.
您可以onPress
像这样直接调用道具来调用:
wrapper.find({ testId: 't-and-c' }).props().onPress();
所以所有的工作测试看起来像这样:
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',
}
},
WebBrowser: {
openBrowserAsync: jest.fn()
}
}));
it('click on terms and conditions link', () => {
const mock = jest.spyOn(WebBrowser, 'openBrowserAsync');
mock.mockImplementation(() => Promise.resolve());
const wrapper = shallow(<AboutScreen />);
wrapper.find({ testId: 't-and-c' }).props().onPress();
expect(mock).toHaveBeenCalledWith('tcUrl'); // Success!
});
推荐阅读
- swift - Swift:如何在 swift 中合并两个领域结果
- azure-sql-database - Microsoft Powerapps,根据列数据过滤掉
- python - 为什么递归加法在python中产生负数?
- html - jQuery 追加不呈现 html - 它显示为文本
- java - 当我已经有 1.8 JRE 时,“仅在源级别 1.8 或更高级别允许引用接口静态方法”
- menu - 挂钩到 Drupal 8 中的添加菜单链接
- javascript - JS 无法查询 MySQL 数据库。错误:connection.query 不是函数
- reactjs - 如何使用 react-create-app 获取代码覆盖率报告?
- regex - golang替换正则表达式的子字符串
- c - 强制 GtkListStore 右对齐列