redux-saga-test-plan ExpectSaga-使用state分支测试reducer

时间:2019-03-19 16:46:06

标签: javascript typescript redux redux-saga redux-saga-test-plan

正确测试我的传奇时,我有些麻烦。问题源于以下事实:运行传奇时,减速器安装在state: {...initialState}上,而我的传奇select效果期望减速器安装在state: {authentication: {...initialState}}

由于这个原因,由于最终状态对象的形状与商店的实际形状不一致,因此我无法完全测试reducer / saga组合。

正在测试的传奇

export default function* rootAuthenticationSaga() {
  while (true) {
      refreshToken = yield select((state: ApplicationRootState) => state.authentication.refreshToken);
      ... more code here
}

我的一项测试如下:

    test('logs the user in if they provide a valid email and password', () => {
      const mockRefreshPoller = createMockTask();
      const initialState = {
        accessToken: '',
        refreshToken: '',
        userId: '',
      }
      return expectSaga(rootAuthenticationSaga)
        .withReducer(authenticationReducer, initialState)
        .provide([
          // some mock providers set up here
        ])
        // ...more asserts here
        .put(authenticationActions.saveTokens({accessToken: 'VALID_ACCESS_TOKEN', refreshToken: 'VALID_REFRESH_TOKEN'}))
        .hasFinalState({
           accessToken: 'VALID_ACCESS_TOKEN',
           refreshToken: 'VALID_REFRESH_TOKEN',
           userId: 'USER_ID',
        })
        .dispatch(authenticationActions.login.request({email: 'VALID_EMAIL', password: 'VALID_PASSWORD'}))
        .run()
    });

在上述测试中,select()失败,因为正确的路径(通过withReducer注入)位于state.refreshToken而非state.authentication.refreshToken

如果我通过withState({authentication: {refreshToken, ...}})注入状态,则select会按预期工作,但是所有的reducer动作都针对状态根发生,最终状态为(错误)形状:

{state: 
  authentication: {
    refreshToken: '',
    ...
  },
  refreshToken: 'VALID_REFRESH_TOKEN',
  ...
}

1 个答案:

答案 0 :(得分:1)

诀窍是通过创建

在相关的“分支”处“安装”相关的减速器。
const reducerUnderTest = createReducer({
  authentication: authenticationReducer,
})

,然后将其传递到具有正确形状状态的withReducer(reducerUnderTest, {authentication: {...initialState}}