Как это случилось, я столкнулся с подобной ситуацией в начале этой недели. Вот как я это решил. Возможно, есть лучшие решения, но в моей ситуации это сработало.
Отказ от ответственности: Я пишу это из памяти непосредственно в поле ответа StackOverflow, поэтому оно может быть не точным на 100%.
Во-первых, вы должны смоделировать Axios, чтобы иметь возможность контролировать вывод API для ваших тестов. Вы никогда не должны выполнять HTTP-запрос из тестового примера, потому что вы не тестируете свой API - вы тестируете, как ваш компонент реагирует на определенный ответ API. Мой проект использует create-react-app
, который настраивает Jest для загрузки макетов из папки __mocks__
в корне проекта.
__mocks__/axios.js
:
export default {
// since you are only testing "axios.post()", I'm only mocking "post"
post: jest.fn()
}
Затем в тесте вашего родительского компонента вы можете указать фиктивную реализацию для функции post
, которая возвращает ответ 200 (это тот случай, когда вы тестируете).
__tests__/App.test.jsx
// in Jest context, this should load from __mocks__/axios.js
import axios from "axios";
test("When valid form is submitted, it should show a success message", () => {
// Axios itself returns a Promise, so the mock should as well
axios.post.mockImplementationOnce(
(url, formData) => Promise.resolve({
status: 200
})
);
const wrapper = mount(<App />);
// Optionally, test the default state to be an empty string
expect(wrapper.state()).toHaveProperty("message");
expect(wrapper.state().message).toBe("");
wrapper.find("input").at(0).simulate("change", {
target: {
value: "a@b.c",
}
});
wrapper.find("form").simulate("submit");
// Optionally, test if Axios was called
expect(axios.post).toHaveBeenCalled();
// More optionally, test if it was called with the correct email address
expect(axios.post).toHaveBeenCalledWith(
expect.any(),
expect.objectContaining({ primaryEmail: "a@b.c" })
);
// Note that even though Axios may have been called, the asynchronous
// Promise may not have completed yet which means the state will not
// have been updated yet. To be safe, let's use setImmediate(), which
// should wait for any pending Promises to complete first
setImmediate(async () => {
// Now we can test that the state has changed
expect(wrapper.state().message).toBe("Your email has been updated.");
});
});