Как проверить ошибки в редукционных действиях - PullRequest
0 голосов
/ 15 октября 2019

В средней функции я могу сделать так:

expect(() => foo()).toThrow();

Но когда я пытаюсь сделать это с помощью действия с избыточностью, я получаю

UnhandledPromiseRejectionWarning и результат теста:Ожидается, что функция выдаст сообщение об ошибке: «Несанкционировано». Но ничего не получилось.

Пример действия:

const someAction = id => async dispatch => {
  try {
    const { data } = await apiCall(id);
    dispatch({ type: ACTION_TYPE, payload: data });
  } catch (err) {
    throw new Error(err);
  }
};

Пример теста:

test('should handle errors', () => {
    const errMsg = 'Unauthorized';
    apiSpy.mockImplementationOnce(() => Promise.reject(errMsg));
    expect(() => store.dispatch(someAction(id))).toThrow(errMsg);
});

Мне кажется, что я здесь что-то упустил.

1 Ответ

1 голос
/ 16 октября 2019

Вот решение:

actionCreator.ts:

import { apiCall } from './apiCall';

export const ACTION_TYPE = 'ACTION_TYPE';

export const someAction = id => async dispatch => {
  try {
    const { data } = await apiCall(id);
    dispatch({ type: ACTION_TYPE, payload: data });
  } catch (err) {
    throw new Error(err);
  }
};

apiCall.ts:

export const apiCall = async (id: string) => ({ data: id });

actionCreator.spec.ts:

import createMockStore from 'redux-mock-store';
import thunk, { ThunkDispatch } from 'redux-thunk';
import { someAction } from './actionCreator';
import { AnyAction } from 'redux';
import * as API from './apiCall';

const mws = [thunk];
const mockStore = createMockStore<{}, ThunkDispatch<{}, any, AnyAction>>(mws);

describe('someAction', () => {
  afterEach(() => {
    jest.restoreAllMocks();
  });
  test('should handle errors', async () => {
    const errMsg = 'Unauthorized';
    const apiSpy = jest.spyOn(API, 'apiCall').mockRejectedValueOnce(errMsg);
    const id = '1';
    const store = mockStore({});
    await expect(store.dispatch(someAction(id))).rejects.toThrow(errMsg);
    expect(apiSpy).toBeCalledWith(id);
  });

  test('should dispatch action correctly', () => {
    expect.assertions(2);
    const apiSpy = jest.spyOn(API, 'apiCall').mockResolvedValueOnce({ data: 'mocked data' });
    const id = '1';
    const store = mockStore({});
    return store.dispatch(someAction(id)).then(() => {
      expect(store.getActions()).toEqual([{ type: 'ACTION_TYPE', payload: 'mocked data' }]);
      expect(apiSpy).toBeCalledWith(id);
    });
  });
});

Результат модульного теста с отчетом о покрытии:

 PASS  src/stackoverflow/58396438/actionCreator.spec.ts (6.631s)
  someAction
    ✓ should handle errors (8ms)
    ✓ should dispatch action correctly (2ms)

------------------|----------|----------|----------|----------|-------------------|
File              |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
------------------|----------|----------|----------|----------|-------------------|
All files         |    84.62 |      100 |       60 |      100 |                   |
 actionCreator.ts |      100 |      100 |      100 |      100 |                   |
 apiCall.ts       |       50 |      100 |        0 |      100 |                   |
------------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        7.747s

Исходный код: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58396438

...