Тестирование Redux Thunk Action Creator

1

У меня есть создатель action для сокращения, который использует сокращение, чтобы сделать некоторую логику, чтобы определить, что нужно отправить в магазин. Это не будет основано на обещаниях, как HTTP-запрос, поэтому у меня возникают некоторые проблемы с тем, как правильно его протестировать. Мне нужно испытание, когда значение соответствует условию, а когда нет. Поскольку создатель действия не возвращает обещание, я не могу запустить.then() в своем тесте. Каков наилучший способ проверить что-то подобное?

Аналогичным образом, я считаю, что это было бы довольно простое тестирование создателя actionRemoveFileMetrics(), поскольку оно действительно возвращает обещание. Но как я могу утверждать, что это вызовет, если значение removeFiles и соответствует условию? Как это можно записать в тесте?

Заранее спасибо, поскольку это заставило меня застрять последние пару дней.

Создатели Action

export const handleSelection = (value, cacheKey) => {
    return dispatch => {
        if (value === "removeFiles") {
            dispatch(getRemoveFileMetrics(cacheKey));
        }
        dispatch({ type: HANDLE_SELECTION, value });
    };
};

export const getRemoveFileMetrics = cacheKey => {
    return dispatch => {
        dispatch({ type: IS_FETCHING_DELETE_METRICS });
        return axios
            .get('../GetRemoveFileMetrics', { params: { cacheKey } })
            .then(response => {
                dispatch({ type: GET_REMOVE_FILE_METRICS, payload: response.data });
            })
            .catch(err => console.log(err));
    };
};

Шутка

it("should dispatch HANDLE_SELECTION when selecting operation", () => {
    const store = mockStore({});
    const value = "switchVersion";
    const expectedAction = [{
        type: MOA.HANDLE_SELECTION,
        value,
    }]; // TypeError: Cannot read property 'then' of undefined
    return store.dispatch(MOA.handleSelection(value)).then(() => {
        const returnedActions = store.getActions();
        expect(returnedActions).toEqual(expectedAction);
    });
});

NEW EDIT

Поэтому, основываясь на ответе Дэнни Делотта, чтобы ответить на обещание, я получил прохождение теста следующим образом:

export const handleSelection = (value, cacheKey) => {
    return dispatch => {
        if (value === "removeFiles") {
            return dispatch(getRemoveFileMetrics(cacheKey));
        }
        return new Promise((resolve, reject) => {
            resolve(dispatch({ type: HANDLE_SELECTION, value }));   
        });
    };
};
Теги:
unit-testing
redux
jest
redux-mock-store

1 ответ

1

Есть ли причина явно не возвращать обещание в вашем создателе действия? Похоже, что getRemoveFileMetrics возвращает обещание, оно просто проглатывается в handleSelection...

Самое простое решение - просто вернуть обещание:

export const handleSelection = (value, cacheKey) => {
    return dispatch => {
        if (value === "removeFiles") {
            return dispatch(getRemoveFileMetrics(cacheKey));
        }
        dispatch({ type: HANDLE_SELECTION, value });
        return new Promise();
    };
};

В противном случае вам нужно будет сделать свои утверждения после завершения цикла событий. Вы можете сделать с помощью setTimeout, завернутого в Promise, чтобы получить поведение .then.

it("should dispatch HANDLE_SELECTION when selecting operation", () => {
    const store = mockStore({});
    const value = "switchVersion";
    const expectedAction = [{
        type: MOA.HANDLE_SELECTION,
        value,
    }];

   store.dispatch(MOA.handleSelection(value));

   // flush outstanding async tasks
   return new Promise(resolve => {
     setTimeout(resolve, 0);
   })
   .then(() => {
      const returnedActions = store.getActions();
      expect(returnedActions).toEqual(expectedAction);
    });
});
  • 0
    Так что я думаю, что нашел исправление, проверьте мое новое редактирование выше, похоже, оно соответствует утверждению.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню