Тестирование с Jest и Enzyme - изменение состояния

Возникла проблема с тестированием реакт компонента. В нем есть функция, реализующая fetch и меняющая состояние с полученными данными:

dbSelectRequest = (url) => {
    fetch(url, {
      method: 'GET',
      credentials: 'same-origin',
      headers: {
        'Content-Type': 'application/json'
      }
    })
      .then(response => response.json())
      .then(response => {
        this.setState({
          [tableName]: response[tableName]
        });
        console.log('---------------STATE AFTER CH----------------', this.state.settings_group)
      });
  };

Тест:

let data = [something]
test('получение данных о группах пользователя', async () => {
    const props = {
      userId: 1
    }
    const wrapper = mount(<Settings {...props}/>);
    const instance = wrapper.instance();
    await fetch.mockResponse(JSON.stringify({settings_group: [data]}));
    await instance.dbSelectRequest('settings_group', 0);
    await expect(wrapper.state().settings_group).toEqual(data);
     });

Для моков использую пакет jest-fetch-mock. Суть проблемы: тест не проходит, тк состояние инстанса не меняется (остается пустым), при этом console.log, написанный в функции, выводит состояние как успешно измененное (тоесть заполненное данными data). Как так? Почему они разные?


Ответы (1 шт):

Автор решения: ThisMan

при этом console.log, написанный в функции, выводит состояние как успешно измененное (тоесть заполненное данными data).

А точно?

Просто, setState сам по себе асинхронный, сразу значение он не поменяет.
Так же у вас dbSelectRequest не возвращает Promise, то есть await dbSelectRequest(...) по сути ничего не дожидается. Надо как минимум return fetch, что бы возвращался Promise.

Что бы дождаться update стейта, можно просто дождаться следующего тика. Типо, что-нибудь вроде:

const waitUpdateState = () => {
  return new Promise((resolve) => {
     setTimeout(resolve, 0);
  });
}
→ Ссылка