我正在使用Jest和Enzyme,我有一个包含navigate
方法调用的组件:
export class LeadList extends React.Component {
render() {
const { navigate } = this.props.navigation;
return (
<List>
{this.props.data.allLeads.map((lead, i) => {
return (
<ListItem
key={i}
onPress={() =>
navigate('Details', lead.id)
}
/>
// ...
</ListItem>
)})}
</List>
);
}
}
我试图测试它是否被正确调用,所以我把它扔到了一起:
const testProps = props => ({
data: {
allLeads: [
{id: 1, name: 'John Doe'},
{id: 2, name: 'Jane Doe'}
],
loading: false,
},
navigation: jest.fn((options, callback) => callback('Details', 1)),
...props,
})
describe('interactions', () => {
let props
let wrapper
beforeEach(() => {
props = testProps()
wrapper = shallow(<LeadList {...props} />)
})
describe('clicking a lead', () => {
beforeEach(() => {
wrapper.find(ListItem).first().prop('onPress')
})
it('should call the navigation callback', () => {
expect(props.navigation).toHaveBeenCalledTimes(1)
})
})
})
输出是:
Expected mock function to have been called one time, but it was called zero times.
处理此问题的正确方法是什么?我需要使用间谍吗?
修改
当我改变它时,我得到了同样的结果:
const testProps = props => ({
// ...
navigation: {navigate: jest.fn()},
...props,
})
it('should call the navigation callback', () => {
expect(props.navigation.navigate).toHaveBeenCalledTimes(1)
})
输出:
expect(jest.fn()).toHaveBeenCalledTimes(1)
Expected mock function to have been called one time, but it was called zero times.
at Object.<anonymous> (__tests__/LeadList-test.js:48:35)
at tryCallTwo (node_modules/promise/lib/core.js:45:5)
at doResolve (node_modules/promise/lib/core.js:200:13)
at new Promise (node_modules/promise/lib/core.js:66:3)
at Promise.resolve.then.el (node_modules/p-map/index.js:46:16)
at tryCallOne (node_modules/promise/lib/core.js:37:12)
at node_modules/promise/lib/core.js:123:15
答案 0 :(得分:4)
你需要一个间谍来测试这个。以下是在ForgotPassword
上查找LoginScreen
按钮并测试其导航到正确屏幕的示例测试。
test('Press Forgot Password Button', () => {
const spy = jest.spyOn(navigation, 'navigate')
const wrapper = shallow(
<LoginScreen
navigation={navigation}
error={{}}
onLogin={jest.fn()}
/>,
)
const forgotButton = wrapper.find('Button').at(0)
forgotButton.props().onPress()
expect(spy).toBeCalledWith('ForgotPassword')
})
答案 1 :(得分:2)
传递给组件的prop navigation
不是函数。它是一个包含名为navigate
的函数的对象。
具有讽刺意味的是,这正是您在组件代码中使用的内容:
const { navigate } = this.props.navigation;
因此,您必须更改您从测试中传递的导航道具:
navigation: {navigate: jest.fn()}
然后在你的测试中:
expect(props.navigation.navigate).toHaveBeenCalledTimes(1)
修改强>
为了实际获得要调用的功能,您必须模拟印刷机。现在代码找到了onPress
函数,但没有调用它。
为此,您可以替换
wrapper.find(ListItem).first().prop('onPress')
带
wrapper.find(ListItem).first().props().onPress()