簡體   English   中英

Redux Mock Store給出'動作必須是普通對象。 使用自定義中間件進行異步操作。

[英]Redux Mock Store giving 'Actions must be plain objects. Use custom middleware for async actions.'

我正在嘗試使用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. Actions must be plain objects. Use custom middleware for async actions. 這有什么不對?

問題是您使用的是redux-thunk中間件,但是一旦您的promise解析,您就不會調度任何操作(您可以檢查如何定義在文檔中使用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中間件提供),我們使用該函數來調度我們的動作(即簡單對象)。

當你打電話給你行動的創建者用正確的參數,你應該回到你的承諾的以便它等待的承諾已經得到解決,執行語句,然后里面的期待:

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

另外,請注意在初始測試中,您希望調度兩個操作,但是您只需要調用一次操作創建者。 你應該在的另一個測試失敗案例。

您可以在此處看到解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM