问题
I am trying to perform some unit testing on my existing react application with Jest and Enzyme. I am totally new to this stuff and accurately I do not know how to approach such test scenarios. I know that to test API request calls I have to perform some "mocking", but how should I write the test for that?. What will be the steps that needs to be followed?
Following is the code snippet I am looking to test.
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>
)
}
}
回答1:
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();
});
});
check this article https://binarapps.com/blog/test-ajax-calls-in-react-component-lifecycle/
回答2:
1) Extract the API call in another method that returns the promise(for eg: fetchCities()) for ease of testing.
2) Mock the axios node module with Jest. Refer docs: https://jestjs.io/docs/en/mock-functions#mocking-modules
3) Use Enzyme to get a reference to your component: https://airbnb.io/enzyme/docs/api/ShallowWrapper/shallow.html
Once that's in place, you can verify if the state is set correctly. For eg:
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);
});
});
How do i improve this answer? It is not what i am expecting as response which is name of the cities.
axios.js (seperate function for promise)
'use strict';
module.exports = {
get: () => {
return Promise.resolve({
data: [
{
id: 0,
name: 'Santa Clara'
},
{
id: 1,
name: 'Fremont'
}
]
});
}
};
Home.test.js (actual test file)
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();
});
});
});
来源:https://stackoverflow.com/questions/52745388/jest-enzyme-unit-test-on-axios-requests-in-componentdidmount