【问题标题】:Testing Redux Thunk Action Creator测试 Redux Thunk Action Creator
【发布时间】:2017-11-30 00:22:40
【问题描述】:

我有一个 redux 动作创建器,它利用 redux-thunk 执行一些逻辑来确定将什么分派到商店。它不是基于承诺的,就像 HTTP 请求一样,所以我在如何正确测试它方面遇到了一些问题。我需要测试值何时满足条件以及何时不满足。由于动作创建者没有返回承诺,我无法在测试中运行 .then() 。测试这种东西的最佳方法是什么?

同样,我相信测试 getRemoveFileMetrics() 动作创建者会非常简单,因为它确实返回了一个承诺。但是,如果值为 removeFiles 并且满足条件,我怎么能断言它会被调用呢?怎么会写在测试中?

在此先感谢,因为这让我在过去的几天里陷入了困境。

动作创作者

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);
    });
});

新编辑

因此,根据 Danny Delott 对返回承诺的回答,我通过了如下测试:

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 }));   
        });
    };
};

【问题讨论】:

    标签: javascript unit-testing redux jestjs redux-mock-store


    【解决方案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();
        };
    };
    

    否则,您需要在事件循环完成后进行断言。您可以使用包装在 Promise 中的 setTimeout 来获得 .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);
        });
    });
    

    【讨论】:

    • 所以我想我找到了一个修复,检查我上面的新编辑,它似乎符合断言。
    猜你喜欢
    • 2018-09-27
    • 2020-08-17
    • 2016-12-11
    • 2020-02-05
    • 2020-02-03
    • 2023-04-01
    • 2021-08-18
    • 2020-01-18
    • 2018-03-15
    相关资源
    最近更新 更多