【问题标题】:Redux Mock Store giving 'Actions must be plain objects. Use custom middleware for async actions.'Redux Mock Store 给出 'Actions must be plain objects。使用自定义中间件进行异步操作。
【发布时间】:2019-04-22 10:23:19
【问题描述】:

我正在尝试使用redux-mock-store 在我的React 应用程序中测试一些异步代码。

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.上面运行时出现以下错误@这里有什么问题?

【问题讨论】:

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


    【解决方案1】:

    问题是您正在使用 redux-thunk 中间件,但是一旦您的承诺解决,您就没有调度任何动作(您可以检查如何定义使用 redux-thunk 的动作创建者documentation)。

    因此,您需要定义一个动作创建者,它使用您的 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 中间件提供)并且我们使用该函数来调度我们的动作(即简单对象)。

    一旦你用正确的参数调用你的action creator,你应该在it中返回你的promise,这样它就会等到promise解决并在then中执行期望em> 声明:

    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 中测试失败案例。

    您可以在here 看到解决方案。

    【讨论】:

    • 运行代码会报错TypeError: actionCreator(...).then is not a function
    • 它应该可以正常工作...您是否在调用dispatch 后附加then 分句?
    • 在您报告的 TypeError 中,您似乎在调用 actionCreator 而不是 dispatch 之后放置了 then 子句我>
    猜你喜欢
    • 2021-03-07
    • 2020-07-24
    • 1970-01-01
    • 2023-02-02
    • 2016-12-20
    • 2017-05-01
    • 2022-11-21
    • 2017-09-30
    相关资源
    最近更新 更多