我正在使用 jest 和酶对使用 create-react-app 创建的 React 应用程序进行单元测试。我有一个 axios 调用,我分别在 axios 调用成功和错误时从另一个组件调用其他函数,如 myfunction.onSuccess()
和 myfunction.onError()
。我已将断言置于 expect(myfunction.onSuccess).toHaveBeenCalledTimes(1);
这适用于 mockResolvedValue
但不适用于 mockRejectedValue
。我发现 mockRejectedValue
不尊重 async-await。
我创建了一个示例代码,并使用 window.alert
作为在 then 和 catch 块中调用的函数,以保持简单,并期望此函数作为断言被调用一次。为什么会有差异以及如何解决这个问题?
异步.js
import React from 'react';
import axios from 'axios';
class Async extends React.Component {
constructor(props) {
super(props);
this.state = {
posts: []
};
}
getAllPosts() {
axios.get(`https://jsonplaceholder.typicode.com/posts`)
.then(response => {
if (response.data) {
this.setState({ posts: response.data });
window.alert("Data fetch Success");
}
}).catch(error => {
window.alert(error.message);
});
}
render() {
return (
<div>
<button onClick={() => { this.getAllPosts() }}>Fetch Posts</button>
<ul>
{this.state.posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
);
}
}
export default Async;
Async.test.js
import React from 'react';
import Async from './Async';
import { shallow } from 'enzyme';
import axios from "axios";
jest.mock("axios");
describe('Async Component', () => {
const wrapper = shallow(<Async />);
const layout = wrapper.instance();
it('to notify success when posts', async () => {
window.alert = jest.fn();
const response = { data: [{ id: '1', title: 'something' }, { id: '2', title: 'something else' }] };
axios.get.mockResolvedValue(response);
await layout.getAllPosts();
expect(layout.state.posts).not.toBe([])
expect(window.alert).toHaveBeenCalledTimes(1);
});
it('to notify failure when error is encountered', async () => {
window.alert = jest.fn();
const error = { message: '500 Internal Server Error' };
axios.get.mockRejectedValue(error);
await layout.getAllPosts();
expect(window.alert).toHaveBeenCalledTimes(1); // why doesn't this work?
});
});