Тестирование Promise.all с Jest / Vuex - PullRequest
0 голосов
/ 04 мая 2020

Я пытаюсь протестировать действие Vuex, которое использует Promise.all для извлечения данных из API, а затем фиксирует мутацию на основе ответа. Тем не менее, и мой тест утверждения (expect.assertions(1)), и тест, чтобы увидеть, был ли вызван коммит, терпят неудачу.

Мое действие:

fetchUserProfile ({ dispatch, commit}) {
      const userAccountFetch = api.get('/user/account');
      const userProfileFetch = api.get('/user/profile');
      const userItemsFetch = api.get(`/user/purchases`);
      Promise.all([
        userAccountFetch.catch((error) => {
          console.error(error);
          return { error, };
        }), 
        userProfileFetch.catch((error) => { 
          console.error(error); 
          return { error, };
        }),
        userItemsFetch.catch((error) => {
          console.error(error);
          return { error, };
        }),
      ]).then((responses) => {
          commit('setUserAccount', {responses});
        }
      });
  }

Мой тест выглядит следующим образом:

jest.mock('@api/api.js', () => ({ get: jest.fn(), }));
const mockApi = require('@api/api.js');

test('fetchUserProfile performs commit on successful fetch', () => {
    const mockResponse = [{userAccount: ....}, {userProfile: ...}, {userItems: ....}];
    mockApi.get.mockReturnValueOnce(Promise.resolve(mockResponse[0]));
    mockApi.get.mockReturnValueOnce(Promise.resolve(mockResponse[1]));
    mockApi.get.mockReturnValueOnce(Promise.resolve(mockResponse[2]));
    expect.assertions(1);
    fetchUserProfile({ commit, state, }).then(() => expect(commit).toHaveBeenCalledTimes(1));
  });

Я включил console.logs в свои действия, и тест переходит к той строке, где я выполняю свой коммит, но по какой-то причине тест не проходит. Я не уверен, что здесь не так. Любая помощь будет чрезвычайно признательна.

1 Ответ

0 голосов
/ 04 мая 2020

Это очень распространенный антипаттерн, в котором функция, использующая обещания, не возвращает обещание, которое может быть связано. Это предотвращает его эффективное использование и тестирование.

Это должно быть:

return Promise.all(...)

Другая проблема заключается в том, что асинхронный тест Jest не возвращает обещание. Это приводит к непроверенному отклонению, которое не влияет на результат теста.

async..await - эффективный способ поддерживать порядок выполнения; async Функция всегда возвращает обещание:

test('fetchUserProfile performs commit on successful fetch', async () => {
    ....
    await fetchUserProfile({ commit, state });
    expect(commit).toHaveBeenCalledTimes(1);
});
...