3

我正在尝试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.这里有什么问题?

4

1 回答 1

4

问题是您正在使用redux-thunk中间件,但是一旦您的承诺解决,您就不会调度任何操作(您可以在文档中查看如何定义使用redux-thunk的操作创建者)。

因此,您需要定义一个操作创建者,它使用您的虚拟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 }));
};

请注意动作创建者如何接收参数调度(由redux-thunk中间件提供),我们使用该函数调度我们的动作(即简单对象)。

一旦你用正确的参数调用你的动作创建者,你应该在它中返回你的承诺,以便它等待直到承诺解决并在then语句中执行期望:

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

您可以在此处查看解决方案。

于 2019-04-22T10:54:57.187 回答