问题描述
我如何测试子组件onclick。
how can i test the child component onclick.
请参见下面的代码段。
// App.js
import React, {Component, Fragment} from 'react'
import Child from './child'
class App extends Component{
state = {
data: null,
enable: false
}
componentDidMount(){
this.getData()
}
getData = async () => {
const response = await fetch('http://www.example.com');
const data = await response.json();
this.setState({
data
})
}
_handleChildClick = () => {
this.setState({
enable: true
})
}
render(){
const {data, enable} = this.state
if(!data){
return (
<div>
Loading
</div>
)
}else{
<Fragment>
<Child
handleChildClick={this._handleChildClick}
/>
</Fragment>
}
}
}
export default App
import React from 'react';
const child = () => {
return(
<div>
<button
className="toggle"
onClick={props.handleChildClick}
>
Toggle
</button>
</div>
)
}
export default child
// App.test.js
import React from 'react';
import {enzyme} from 'enzyme';
import App from './App';
describe("App test cases", () => {
it('should trigger _handleChildClick', async () => {
window.fetch = jest.fn().mockImplementation(() => ({
status: 200,
json: () => new Promise((resolve, reject) => {
resolve(
{
name: "some data"
}
)
})
}))
const mountWrapper = await mount(<App />)
setTimeout(() => {
mountWrapper.update()
const SpyhandleChildClick = jest.spyOn(mountWrapper.instance(),'_handleChildClick')
mountWrapper.find('.toggle').simulate('click')
expect(SpyhandleChildClick).toHaveBeenCalled() // not called
},0)
})
})
推荐答案
考虑。
如果必须在测试中执行异步任务,则必须一直等到异步内容完成。
If you have to do asynchronous tasks in your tests you always have to await until the asynchronous stuff is completed.
setTimeout(() => {
mountWrapper.update()
const SpyhandleChildClick = jest.spyOn(mountWrapper.instance(),'_handleChildClick')
mountWrapper.find('.toggle').simulate('click')
expect(SpyhandleChildClick).toHaveBeenCalled() // not called
},0)
在代码中,您有一个超时段。此代码块内的任何测试条件都不会被评估,因为到了评估时,由于aync性质,您的测试会话将已经结束。
Above in your code you have a timeout segment. Any test condition inside this code block will not be evaluated since by the time they are evaluated you 'test session' will already be over due to the aync nature.
酶库的问题,您必须在侦查反应组件以锁定该方法后强制更新反应组件。
请关注github问题以获取更多信息:
There seem to be a problem with the enzyme library where you have to force update the react component after spying for it to latch on to the method.Please follow the github issue for more information : https://github.com/airbnb/enzyme/issues/365
我还整理了一下您的测试代码,使其更易于理解!
I also cleaned up your test code a bit to make it more understandable!
// App.test.js
import React from 'react';
import {enzyme} from 'enzyme';
import App from './App';
describe("App test cases", () => {
it("should trigger _handleChildClick", async () => {
window.fetch = jest.fn().mockImplementation(() => ({
status: 200,
json: () =>
new Promise((resolve, reject) => {
resolve({
name: "some data"
});
})
}));
const mountWrapper = mount(<App />);
mountWrapper.update();
console.log("mountWrapper", mountWrapper.debug()); // showing the loader one
//[FIX]This code will block and wait for your asynchronous tasks to be completed
await new Promise(res => setTimeout(() => res(), 0));
mountWrapper.update();
console.log("mountWrapper", mountWrapper.debug()); // nothing showing
expect(mountWrapper.find(".toggle").length).toEqual(1);
//[FIX]Get a reference from the wrapper and force update after the spyOn call
const instance = mountWrapper.instance();
const spy = jest.spyOn(instance, "_handleChildClick");
instance.forceUpdate();
mountWrapper.find(".toggle").simulate("click");
expect(spy).toHaveBeenCalled();
});
});
实时演示链接:单击浏览器上的测试标签以查看测试结果
Live Demo Link: Click on the 'Tests' tab on the browser to see the test resultshttps://codesandbox.io/s/mz21kpm37j
这篇关于在箭头功能上进行测试时,酶onclick间谍toHaveBeenCalled测试不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!