Я хочу протестировать событие асинхронного щелчка в React, которое выполняет две вещи:
1. Выполните вызов API для отправки запроса POST.
2. После успешного выполнения запроса на публикацию обновите состояние в компоненте верхнего уровня.
Я хочу знать, как лучше всего проверить, что события произошли в этом порядке.
Мне удалось использовать 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?
Еще один похожий пост: Тестирование API Call in React - Состояние не обновляется , однако никто не ответил на него.