我正在尝试测试异步等待功能,但是我收到了错误消息。
●应该处理getGIF事件›应该处理getGIF事件
expect(jest.fn()).toHaveBeenCalledTimes(1)
Expected mock function to have been called one time, but it was called zero times.
我不确定如何测试异步等待功能,因此我以该博客为例https://medium.com/@rishabhsrao/mocking-and-testing-fetch-with-jest-c4d670e2e167
App.js
import React, {Component} from 'react';
import logo from './logo.svg';
import './App.css';
import Card from './Card';
import PropTypes from "prop-types";
const Styles = {
marginTop: '100px',
inputStyle: {
borderRadius: '0px',
border: 'none',
borderBottom: '2px solid #000',
outline: 'none',
focus: 'none'
}
}
class App extends Component {
constructor(props) {
super(props);
this.state = {
query: '',
title: undefined,
url: undefined
}
this.onChange = this.onChange.bind(this);
}
onChange(e) {
this.setState({query: e.target.value})
}
// testing this function
getGIY = async(e) => {
e.preventDefault();
const { query } = this.state;
await fetch(`http://api.giphy.com/v1/gifs/search?q=${query}&api_key=iBXhsCDYcnktw8n3WSJvIUQCXRqVv8AP&limit=5`)
.then(response => response.json())
.then(({ data }) => {
this.setState({
title: data[0].title,
url: data[0].images.downsized.url
});
})
.catch( (err) =>{
console.log(err)
});
}
render() {
return (
<div className="col-md-6 mx-auto" style={Styles}>
<h1 className="gif-title">Random GIF fetch</h1>
<form className="form-group" onSubmit={this.getGIY}>
<input
style={Styles.inputStyle}
className="form-control"
type="text"
value={this.state.query}
onChange={this.onChange}
placeholder="Search GIF..."/>
<button type="submit" className="btn btn-primary mt-4">Get GIF</button>
</form>
<Card title={this.state.title} url={this.state.url}/>
</div>
);
}
}
PropTypes.propTypes = {
onChange: PropTypes.func.isRequired,
getGIY:PropTypes.func.isRequired,
title:PropTypes.string.isRequired,
url:PropTypes.string.isRequired
}
export default App;
App.test.js
import React from 'react';
import ReactDOM from 'react-dom';
import {shallow} from 'enzyme';
import App from './App';
describe('Should handle getGIF event', ()=> {
it('should handle getGIF event', done => {
const component = shallow(<App/>)
const mockSuccessResponse = {};
const mockJsonPromise = Promise.resolve(mockSuccessResponse);
const mockQuery = "Owl"
const mockFetchPromise = Promise.resolve({
json:() => mockJsonPromise,
});
jest.spyOn(global, 'fetch').mockImplementation(()=> mockFetchPromise);
expect(global.fetch).toHaveBeenCalledTimes(1);
expect(global.fetch).toHaveBeenCalledWith(`http://api.giphy.com/v1/gifs/search?q=${mockQuery}&api_key=iBXhsCDYcnktw8n3WSJvIUQCXRqVv8AP&limit=5`);
process.nextTick(() => { // 6
expect(component.state()).toEqual({
// ... assert the set state
});
global.fetch.mockClear(); // 7
done(); // 8
});
})
})
最佳答案
您可以像这样测试它:
import React from 'react';
import { shallow } from 'enzyme';
import App from './App';
describe('Should handle getGIF event', () => {
let mock, actualFetch;
beforeEach(() => {
mock = jest.fn();
actualFetch = global.fetch;
global.fetch = mock;
});
afterEach(() => {
global.fetch = actualFetch;
});
it('should handle getGIF event', async () => {
const component = shallow(<App />);
component.setState({ query: 'Owl' });
mock.mockResolvedValue({
json: () => Promise.resolve({
data: [{
title: 'the title',
images: { downsized: { url: 'the url' }}
}]
})
});
const form = component.find('form');
await form.props().onSubmit({ preventDefault: () => {} });
expect(mock).toHaveBeenCalledWith('http://api.giphy.com/v1/gifs/search?q=Owl&api_key=iBXhsCDYcnktw8n3WSJvIUQCXRqVv8AP&limit=5'); // Success!
expect(component.state('title')).toBe('the title'); // Success!
expect(component.state('url')).toBe('the url'); // Success!
});
});
细节
fetch
可能没有在Node.js环境中定义,因此只需抓住它,然后用模拟代替它,然后恢复它是一个好方法。使用
.setState
设置组件状态。使用
.find
获取form
,并使用.props
访问其道具并调用其onSubmit
函数。使用
async
测试函数和await
Promise
返回的onSubmit
,以便在继续之前完全完成。使用
.state
查询组件状态。