Сначала тебе нужно как-то издеваться fetch
. Отправка реального запроса не только нарушает изоляцию юнит-тестов, но и повышает риск возникновения противоречий. Также сложнее ждать ответа, когда вы не знаете, когда он может закончиться. Есть разные способы достичь этого. jest-fetch-mock
является одним из них.
Также я советую вам не проверять state
, а проверять render()
результаты.
function getName(wrapper) {
return wrapper.find('.App > div').at(0).props().children;
}
it('should handle click correctly', async () => {
fetch.mockResponseOnce(JSON.stringify({ name: '12345' }));
const wrapper = shallow(<App />);
expect(wrapper.find('button').length).toBe(1);
expect(getName(wrapper)).toEqual("Random Value");
wrapper.find('button').simulate('click');
await Promise.resolve();
expect(getName(wrapper)).toEqual("peter");
});
Что здесь происходит. await Promise.resolve()
просто ждет, пока все выполненные обещания не будут выполнены. Это означает, что без этого наш поддельный ответ не будет выполняться между нажатием кнопки и expect
.
Еще один способ получить положительный результат - заставить handleClick()
вернуть Обещание, которого мы можем ожидать:
...
handleClick = () => {
const currentContext = this;
return fetch('http://api-call/getdata')
.then(function(response) {
return response.json();
})
.then(function(jsonData) {
// jsonData.name = "peter"
currentContext.setState({name: jsonData.name});
})
}
....
it('should handle click correctly', async () => {
....
expect(getName(wrapper)).toEqual("Random Value");
await wrapper.find('button').simulate('click');
expect(getName(wrapper)).toEqual("peter");
});
или без синтаксического асинхронного ожидания:
it('should handle click correctly', () => {
....
expect(getName(wrapper)).toEqual("Random Value");
return wrapper.find('button').simulate('click').then(() => {
expect(getName(wrapper)).toEqual("peter");
});
});
Но мне действительно не нравится этот способ, так как обработчик событий должен возвращать Promise, который он обычно не делает.
Подробнее о микрозадачах (обещаниях) / макрозадачах (таймерах, событиях), которые вы можете прочитать здесь: https://abc.danch.me/microtasks-macrotasks-more-on-the-event-loop-881557d7af6f
Подробнее о тестировании асинхронного кода в jest, лучше посмотрите их документы: https://jestjs.io/docs/en/asynchronous