- Нам нужно макет
fetchRandom
, поэтому во время тестирования реальный запрос не будет отправлен.
import { fetchRandom } from "../resources/api";
jest.mock("../resources/api"); // due to automocking fetchRandom is jest.fn()
// somewhere in the it()
fetchRandom.mockReturnValue(Promise.resolve({ data: { images: ..., title: ..., id: ...} }))
Поскольку mocking - это Обещание (разрешено, но все еще обещано), нам нужно либо
setTimeout
, либо
await <anything>
, чтобы код компонента понял, что это Обещание разрешено. Это все о
очереди микрозадач / макрозадач .
wrapper.find('button').simulate('click');
await Promise.resolve();
// component has already been updated here
или
it("test something" , (done) => {
wrapper.find('button').simulate('click');
setTimeout(() => {
// do our checks on updated component
done();
}); // 0 by default, but it still works
})
Кстати, вы уже сделали это с
await instance.handleClick();
, но для меня это выглядит так же, как сказать
await 42;
И, кроме того, это работает (см. Ссылку на микрозадачи / макрозадачи). Я считаю, что это ухудшит читаемость тестов («что возвращает handleClick, что нам нужно ожидать?»). Поэтому я предлагаю использовать громоздкие, но менее запутанные await Promise.resolve();
или даже await undefined;
Обращение к
state
и непосредственный вызов методов экземпляра являются анти-шаблонами. Просто цитата (
Кент С. Доддс , с которой я полностью согласен):
В итоге, если ваш тест использует instance () или state (), знайте, чтовы тестируете вещи, о которых пользователь, возможно, даже не подозревал или даже заботился о них, что еще больше расширит ваши тесты и даст вам уверенность в том, что все будет работать, когда ваш пользователь их использует.
Давайте проверимвместо этого результат рендеринга:
import Loader from "./library/Loader";
...
wrapper.find('button').simulate('click');
expect(wrapper.find(Loader)).toHaveLength(1);
await Promise.resolve();
expect(wrapper.find(Loader)).toHaveLength(1);
expect(wrapper.find(Gif).prop("data")).toEqual(data_we_mocked_in_mock)
Давайте получим это в целом:
import {shallow} from "enzyme";
import Gif from "./Gif";
import Loader from "./library/Loader";
import { fetchRandom } from "../resources/api";
jest.mock( "../resources/api");
const someMockForFetchRandom = { data: { id: ..., images: ..., title: ... }};
it("shows loader while loading", async () => {
fetchRandom.mockReturnValue(Promise.resolve(someMockForFetchRandom));
const wrapper = shallow(<RandomGif />);
expect(wrapper.find(Loader)).toHaveLength(0);
wrapper.find('button').simulate('click');
expect(wrapper.find(Loader)).toHaveLength(1);
await Promise.resolve();
expect(wrapper.find(Loader)).toHaveLength(0);
});
it("renders images up to response", async () => {
fetchRandom.mockReturnValue(Promise.resolve(someMockForFetchRandom));
const wrapper = shallow(<RandomGif />);
wrapper.find('button').simulate('click');
expect(wrapper.find(Gif)).toHaveLength(0);
await Promise.resolve();
expect(wrapper.find(Gif).props()).toEqual( {
id: someMockForFetchRandom.data.id,
imageUrl: someMockForFetchRandom.data.images.downsized_large.url,
staticImageUrl: someMockForFetchRandom.data.images.downsized_still.url,
title: someMockForFetchRandom.data.title
});
});