Búsqueda de sitios web

javascript - redux-saga-test-plan expectSaga- Probando el reductor con rama de estado


Estoy teniendo un poco de problema para probar correctamente mi saga. El problema proviene del hecho de que al ejecutar la saga, el reductor está montado en state: {...initialState} mientras que mis efectos select de la saga esperan que el reductor esté montado en state: {authentication: {...initialState}}

Debido a esto, no puedo probar completamente la combinación reducer/saga, ya que la forma del objeto de estado final no es consistente con la forma real del store.

La saga que se está probando:

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

Una de mis pruebas es la siguiente:

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

En la prueba anterior, el select() falla ya que la ruta correcta (con inyección mediante withReducer) está en state.refreshToken y no en state.authentication.refreshToken

Si inyecto el estado a través de withState({authentication: {refreshToken, ...}}), entonces el select funciona como se espera, pero todas las acciones del reductor ocurren en la raíz del estado, con mi estado final teniendo la forma (incorrecta):

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

Respuesta #1

El truco de esto era "montar" el reductor en cuestión en la "rama" correcta creando un

const reducerUnderTest = createReducer({
  authentication: authenticationReducer,
})

y pasar eso en el withReducer(reducerUnderTest, {authentication: {...initialState}} con el estado de forma correcta.