Redux Mock Store с надписью «Действия» должен быть простым объектом.Используйте пользовательское промежуточное ПО для асинхронных действий. ' - PullRequest
0 голосов
/ 22 апреля 2019

Я пытаюсь протестировать некоторый асинхронный код в моем приложении React, используя redux-mock-store .

const configureMockStore = require('redux-mock-store').default;
const thunk = require("redux-thunk").default;

const middlewares = [thunk];
const mockStore = configureMockStore(middlewares);

const dummy = () => {
  // Mock Ajax call
  return new Promise((resolve, reject) => {
      setTimeout(() => resolve({data: 'data'}), 200)
  })
};

describe("Redux Mock Store", () => {
  it("Test Dummy Ajax call", () => {
    const expectedActions = [
      { type: "SUCCESS", payload: "success" },
      { type: "FAILURE", error: { Error: "Error" } }
    ];
    const store = mockStore({});

    store.dispatch(dummy().then(() => {
              expect(store.getActions()).toEqual(expectedActions) 
           }).catch(error => { console.log(error) }))
  });
});

Я использую Jest для запуска этого теста.Я получаю следующую ошибку при запуске выше теста Actions must be plain objects. Use custom middleware for async actions. Что здесь не так?

1 Ответ

0 голосов
/ 22 апреля 2019

Проблема в том, что вы используете redux-thunk middleware, но вы не отправляете никаких действий после того, как ваше обещание разрешено (вы можете проверить, как определить создателя действия, который использует redux-thunk в документации ).

Итак, вам нужно определить создателя действия, который использует ваш запрос dummy ajax и отправляет действие после его завершения:

const dummy = () => {
    // Mock Ajax call
    // Note that you are not capturing any error in here and you are not
    // calling the reject method, so your *catch* clausule will never be
    // executed.
    return new Promise((resolve, reject) => {
        setTimeout(() => resolve({ data: 'success' }), 200);
    });
};

const actionCreator = () => (dispatch) => {
    return dummy()
        .then(payload => dispatch({ type: 'SUCCESS', payload }))
        .catch(error => dispatch({ type: 'FAILURE', error }));
};

Обратите внимание, как создатель действия получает параметр dispatch (который предоставляется промежуточным программным обеспечением redux-thunk ), и мы используем эту функцию для отправки наших действий (которые являются простыми объектами).

После того, как вы вызвали создателя действия с правильными параметрами, вы должны вернуть свое обещание в it , чтобы оно дождалось разрешения обещания и выполнило ожидания в , а затем утверждение:

describe('Redux Mock Store', () => {
    it('Test Dummy Ajax call', () => {
        const expectedActions = [
            { type: 'SUCCESS', payload: { data: 'success' } },
        ];
        const store = mockStore({});

        return store.dispatch(actionCreator()).then(() => {
            expect(store.getActions()).toEqual(expectedActions);
        });
    });
});

Кроме того, примите во внимание, что в своем первоначальном тесте вы ожидаете отправки двух действий, но вызываете своего создателя действия только один раз. Вы должны проверить случай отказа в другом it .

Вы можете увидеть работающее решение здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...