reactjs - 如何测试 async/await API 调用和更新 React 状态
问题描述
我想在 React 中测试一个异步点击事件,它做了两件事: 1. 进行 API 调用以发送 POST 请求。2. post请求成功后,更新顶级组件的状态。
我想知道测试事件是否按此顺序发生的最佳方法是什么。
我能够用来jest-fetch-mock
模拟 API 调用。但我不确定如何测试API 生成后是否执行状态更新。此外,状态更新是从顶级组件向下传递到该子组件的函数。
在 Feedback.jsx 中,updateMembershipStatus
是从另一个名为ManageMembership
.
// This component saves feedback
class Feedback extends PureComponent {
// ...
async handleSubmit (event) {
event.preventDefault();
const {otherReason} = this.state,
{id, updateMembershipStatus} = this.props;
try {
// 1. Make an API call
const saveReason = await MembershipStatusAPI.updateOtherCancelReason(id, otherReason);
// 2. Update membership status
updateMembershipStatus("Feedback");
} catch (error) {
console.error("Oops, handleSubmit failed!", error);
}
}
render () {
const {isDisabled, otherReason} = this.state;
return (
<div>
<div>
Please let us know your feedback
</div>
<textarea
className="feedback-input"
onChange={this.handleChange}
value={otherReason}
/>
<button
disabled={isDisabled}
onClick={(e) => this.handleSubmit(e)}
type="submit"
value="Submit"
>
Cancel my membership
</button>
</div>
);
}
}
ManageMembership.jsx 是顶级组件
class MembershipManagement extends PureComponent {
// ...
constructor (props) {
super(props);
this.state = {
"membershipStatus": this.getCurrentStatus(),
};
}
updateMembershipStatus = (event) => {
if (event === "Feedback") {
this.setState({"membershipStatus": "Pending Cancellation"});
}
}
}
我的测试,FeedbackTest.jsx
describe("<Feedback /> button", () => {
let handleSubmit = null,
wrapper = null;
const updateOtherCancelReason = (url) => {
if (url === "google") {
return fetch("https://www.google.com").then(res => res.json());
}
return "no argument provided";
};
beforeEach(() => {
handleSubmit = jest.fn();
wrapper = mount(
<Feedback
disabled
id={1234567}
/>
);
fetch.resetMocks();
});
it("should trigger handleSubmit asynchronously: it should call updateOtherCancelReason API first to save comments, then update state", async () => {
fetch.mockResponseOnce(JSON.stringify({"other_reason": "I am moving to Mars."}));
wrapper.find("button").simulate("click");
const callAPI = await updateOtherCancelReason("google");
expect(callAPI.other_reason).toEqual("I am moving to Mars.");
expect(fetch.mock.calls.length).toEqual(1);
// How to test async code here?
});
上面的这个测试通过了,因为我使用了 jest-fetch-mock 来模拟一个 API 调用,它给了我们一个模拟响应。如何测试是否updateMembershipStatus
被调用并已成功将 ManageMembership.jsx 中的状态更新为“待取消”?
另一个类似的帖子:Testing API Call in React - State not updates,但是没有人回答它。
解决方案
我会为此使用 react-testing-library。如果由于某些异步操作,某些项目出现在屏幕上,我们可以像这样测试它:
await wait(() => getByText(container, 'some-item'))
// make asserts
推荐阅读
- python - 如何在 python 中使用嵌套循环打印以下模式?
- c++ - C++ | 将字符串推入空向量会导致第一个元素被破坏?
- python - 将 Python 的 Keras 用于神经网络时出现类型错误
- python - Python 抓取网站 w/BeautifulSoup4 显示具有类名的表的属性错误
- wordpress - 如何从特定类别中提取最新帖子
- java - 这是用 java 12 编写的,但如果我在 java 15 上运行它,它会引发异常错误
- python - 如何替换 tf.train.batch ,因为它已被弃用
- c++ - 从多个模板类参数中推导可变模板
- vba - 如何在 MS Word vba 中取消选择形状?
- javascript - 为导入添加 .js 扩展名