我正在尝试使用Jest和Enzyme在我现有的react应用程序上执行一些单元测试。我对这些东西完全陌生,准确地说,我不知道该如何处理这样的测试场景。我知道要测试API请求调用,我必须执行一些“模拟”,但是我应该如何为此编写测试?将需要遵循哪些步骤?
以下是我要测试的代码段。
Home.js
import React,{Component} from 'react'
import axios from 'axios';
import {Link} from 'react-router-dom';
import FacilityModal from '../Table/FacilityModal';
class Home extends Component {
state = {
cities:[],
name:''
}
componentDidMount() { axios.get('/cities').then(res => {
this.setState({cities:res.data})
console.log("Oza" + JSON.stringify(res))
}); console.log(this.state.cities) }
render(){
let postList = this.state.cities.map(city =>
{
return(
<div key = {city.id}>
<p>
<Link to = {'/'+city.id}>{city.name}</Link></p>
</div>
)
})
return(
<div className = 'align'>All Facilities (NCAL)
<div className="hr-sect">OR</div>
<div className = 'Modal'>
{postList}
</div>
<FacilityModal cityname = {this.props} />
</div>
)
}
}
答案 0 :(得分:0)
1)用另一种方法返回API(例如fetchCities())提取API调用,以简化测试。
2)用Jest模拟axios节点模块。请参阅文档:https://jestjs.io/docs/en/mock-functions#mocking-modules
3)使用酶获取对您的组件的引用:https://airbnb.io/enzyme/docs/api/ShallowWrapper/shallow.html
就位后,您可以验证状态是否正确设置。例如:
test('should fetch users', () => {
const wrapper = shallow(<Home/>);
const resp = {data: [{cities: ['NY']}]};
axios.get.mockResolvedValue(resp);
wrapper.instance().fetchCities().then(resp => {
expect(wrapper.state('cities')).toEqual(resp.data.cities);
});
});
如何改善此答案?我所期望的不是城市的名字。
axios.js(承诺的单独功能)
'use strict';
module.exports = {
get: () => {
return Promise.resolve({
data: [
{
id: 0,
name: 'Santa Clara'
},
{
id: 1,
name: 'Fremont'
}
]
});
}
};
Home.test.js(实际测试文件)
import React from 'react';
import { shallow,configure } from 'enzyme';
import Home from './Home';
import axios from 'axios';
import Adapter from 'enzyme-adapter-react-16';
configure({adapter:new Adapter()});
jest.mock('axios');
describe('Home component', () => {
describe('when rendered', () => {
it('should fetch a list of cities', () => {
const getSpy = jest.spyOn(axios, 'get');
const cityInstance = shallow(
<Home/>
);
expect(getSpy).toBeCalled();
});
});
});
答案 1 :(得分:0)
import React from 'react';
import axios from 'axios';
export default class ArticleList extends React.Component {
constructor(props) {
super(props);
this.state = {
articles: []
}
}
componentDidMount() {
return axios.get('GET_ARTICLES_URL').then(response => {
this.setState({
articles: response.data
});
});
}
render() {
return (
<ul>
{this.state.articles.map(a => <li><a href={a.url}>{a.title}</a></li>)}
</ul>
)
}
}
// ---------
import React from 'react';
import { shallow } from 'enzyme';
import App from './App';
jest.mock('axios', () => {
const exampleArticles = [
{ title: 'test article', url: 'test url' }
];
return {
get: jest.fn(() => Promise.resolve(exampleArticles)),
};
});
const axios = require('axios');
it('fetch articles on #componentDidMount', () => {
const app = shallow(<App />);
app
.instance()
.componentDidMount()
.then(() => {
expect(axios.get).toHaveBeenCalled();
expect(axios.get).toHaveBeenCalledWith('articles_url');
expect(app.state()).toHaveProperty('articles', [
{ title: 'test article', url: 'test url' }
]);
done();
});
});
查看本文https://binarapps.com/blog/test-ajax-calls-in-react-component-lifecycle/