javascript - redux-saga-test-plan expectSaga- State dalıyla reducer testi


Saga'mı düzgün bir şekilde test etmekte biraz sorun yaşıyorum. Sorun, saga çalıştırıldığında reducer'ın state: {...initialState} üzerinde monte edilmesinden kaynaklanıyor, oysa saga'mın select efektleri reducer'ın state: {authentication: {...initialState}} üzerinde monte edilmesini bekliyor.

Bundan dolayı, nihai durum nesnesinin şekli mağazanın gerçek şekliyle tutarsız olduğu için reducer/saga kombinasyonunu tamamen test edemiyorum.

Test edilen destan:

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

Testlerimden biri şöyledir:

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

Yukarıdaki testte, doğru yol (withReducer ile enjeksiyon ile) state.refreshToken olduğu için select() başarısız olur, state.authentication.refreshToken değil.

Eğer durumu withState({authentication: {refreshToken, ...}}) ile enjekte edersem, select beklenildiği gibi çalışıyor, ama tüm reducer aksiyonları durum kökü üzerinde gerçekleşiyor ve benim nihai durumum (yanlış) şekliyle şöyle oluyor:

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

Cevap #1

Bunun püf noktası, ilgili azaltıcıyı doğru "dal" üzerinde "monte etmek" için bir

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

ve bunu doğru biçimdeki state ile withReducer(reducerUnderTest, {authentication: {...initialState}}'e geçirmek.