2017-02-09 74 views
4

我遵循Redux Sagas的文檔並創建了一組測試,但它們對我來說似乎非常脆弱。每當我更新我的任何傳奇的邏輯時,我的測試都失敗了。這引起了我頭腦中的警鐘,並讓我認爲我做錯了事。單元測試Redux Sagas

下面是一個例子傳奇其與API通信加載用戶的配置文件,並將其存儲在終極版狀態:

export function* userAuthCheck() { 
    try { 
     yield put({ type: START_HTTP }); 

     const me = yield apply(user, user.me); 
     const organisations = yield apply(user, user.organisations, [me.body.data.id]); 

     yield put({ 
      type: USER_AUTH_SUCCESS, 
      redirect: true, 
      state: { 
       account: me.body.data, 
       organisations: organisations.body.data, 
      }, 
     }); 
    } catch (error) { 
     yield put({ type: USER_AUTH_REFRESH }); 
    } finally { 
     yield put({ type: COMPLETE_HTTP }); 
    } 
} 

這裏有相應的測試:

it('can successfully call the API',() => { 
    const generator = userAuthCheck(); 

    expect(generator.next().value).toEqual(put({ type: START_HTTP })); 
    expect(generator.next().value).toEqual(call(user.me)); 

    expect(generator.next().value).toEqual(put({ 
     type: USER_AUTH_SUCCESS, 
     state: { user: undefined }, 
    })); 

    expect(generator.next().value).toEqual(put({ type: COMPLETE_HTTP })); 
}); 

你可能會注意到,測試將實際上失敗,如果運行,因爲我沒有更新它,因爲我做了一些最近更新的傳奇。這就是我開始思考這件事的那種事情。

有沒有更好的方法來測試我的傳奇?是否有可能從頭到尾運行它們,模擬出不同的API響應並聲明正確的事情被調度到狀態?

這些都是文檔我一直在下面:https://redux-saga.github.io/redux-saga/docs/introduction/BeginnerTutorial.html

+3

也許這可能有所幫助:https://github.com/jfairbank/redux-saga-test-plan – jkrnak

+1

看起來不錯 - 看起來我可以很容易地用'next()'模擬響應,但我仍然需要每次更改傳奇時更新測試。當使用生成器函數和yield時,這可能是不可避免的。 – edcs

回答

1

我喜歡嘲笑商店測試它,所以你比如它會是這樣的:

import configureMockStore from "redux-mock-store"; 
import createSagaMiddleware from "redux-saga"; 
import rootSaga from "pathToRootSaga/rootSaga"; 
import {userAuthCheckActionCreator} from "yourPath/UserActionCreators"; 

it('can successfully call the API',() => { 
    const sagaMiddleware = createSagaMiddleware(); 
    const mockStore = configureMockStore([sagaMiddleware]); 
    const store = mockStore({}); 
    sagaMiddleware.run(rootSaga); 

    const expectedActions = [ 
    { 
     type: START_HTTP 
    }, 
    { 
     type: USER_AUTH_SUCCESS, 
     redirect: true, 
     state: { 
      account: me.body.data, 
      organisations: organisations.body.data, 
     } 
    }, 
    { 
     type: COMPLETE_HTTP 
    } 
    ]; 

    store.dispatch(userAuthCheckActionCreator()); 
    expect(store.getActions()).toEqual(expectedActions); 
}); 

我喜歡這種方法,我可以清楚地看到,如果行動的整個序列是按照預期的順序發送。另外,所有事情都是在模擬商店的背景下發生的,讓Saga中間件調度行爲,所以你不需要操縱生成器函數。