2016-11-10 36 views
1

我有一個異步操作創建器,它被分成兩個動作,一個用來表示一個動作的開始,另一個表示動作的結束。在異步行動的創建者中間的Web請求依賴於第一同步調度設置的值:如何測試依賴先前調度調用的異步操作創建者?

export function changeFilter(from, to) { 
    return (dispatch, getState, { fetch }) => { 
    // Updates the state with the new values and sets a loading flag 
    dispatch(changeFilterRequest(from, to)); 

    // Now I want to use those newly-set values to build a query 
    // string. However, the stubbed implementation of `dispatch` 
    // doesn't use reducers, so `getState` continues to return the 
    // original value. 
    const { activeUsers } = getState(); 
    return doSomeWebRequest(fetch, activeUsersParams(activeUsers)) 
     .then(response => dispatch(changeFilterSuccess(response))) 
    }; 
} 

implementation of redux-mock-store's dispatch是相當稀疏,而在(明顯)事後,我們從來沒有通過任何減速的嘲笑商店。

這意味着第一個dispatch調用沒有機會更新第二個調度調用依賴的狀態。我們所做的Web請求具有tofrom日期的原始值,而不是異步操作調用中的更新值。

我想避免直接使用到changeFilter傳遞因爲可能有內changeFilterRequest施加到參數進一步轉化的fromto值。直接依靠getState的結果也可以讓我幹掉少數幾種以不同方式過濾的類似方法。

這些類型的測試應該遵循什麼樣的模式?我應該採用不同的方式來組織我的行動創造者嗎?

回答

1

我認爲你的單元測試應該是精確的,並且只關注你想要測試的功能的範圍,即changeFilter。假設您有changeFilterRequest的另一個單元測試,測試如何計算activeUsers並將其添加到商店,activeUsers作爲changeFilterRequest的副作用在商店中創建的事實應該超出您的測試範圍,因爲changeFilter應該不在意如何計算activeUsers。我認爲您可以在您的模擬商店中安全地添加activeUsers的任何虛擬值,該值不一定取決於您傳遞給changeFilterRequesttofrom的值,並確保您的功能正確地從商店中讀取該值並將其傳遞到activeUsersParams

這麼說,我強烈建議redux-saga作爲替代redux-thunk來處理異步操作,只是因爲它使測試這些樣的行動,很容易,而不必因爲你的所有行動將是純創造嘲笑或測試副作用。