测试redux-observable史诗的错误处理

时间:2017-04-29 07:11:28

标签: redux rxjs rxjs5 reactivex redux-observable

我在这里使用redux-observable并在测试错误处理方面遇到了一些问题。

请参阅以下注销用户史诗:

const logoutUserEpic = (action$) => action$
    .ofType(LOGOUT_USER)
    .mergeMap(() =>
        Observable.from(
            graphQl(AuthLogout)
                .catch((error) => failure(error))
        )
        .mergeMap(() => Observable.of(
                receive(),
                push('/login')
            )
        )
    )

这是一项测试,可以模拟graphQl服务,以确保在承诺拒绝时触发失败操作:

it('should return the error action', () => {
    const error = Error('fail')
    request.graphQl = () => Promise.reject(error)

    const action$ = ActionsObservable.of((logoutUser()))

    return logoutUserEpic(action$)
    .toArray()
    .forEach((actions) => {
        expect(actions).toEqual([{
            meta: { isFetching: false },
            payload: error,
            type: FAILURE
        }])
    })
})

在测试中,它调度在mergeMap中展平的动作,而不是catch中预期的失败动作。

将错误处理设置为这样是有效还是我用RxJ显示我的无效?

1 个答案:

答案 0 :(得分:2)

问题是你正在捕获Promise本身的错误,然后你的mergeMap忽略了Promise的结果,所以你丢掉了failure(error)(可能是一个错误动作)< / p>

const logoutUserEpic = (action$) => action$
    .ofType(LOGOUT_USER)
    .mergeMap(() =>
        Observable.from(
            graphQl(AuthLogout)
                .catch((error) => failure(error))
                // If there is an error, you caught it and transformed it
                // instead into a failure(error) down the success path
        )
        // If there was an error, it is now no longer an error and this
        // mergeMap will just throw that failure(error) away
        .mergeMap(() => Observable.of(
                receive(),
                push('/login')
            )
        )
    )

相反,您应该使用RxJS捕获错误,在这种情况下将其放在mergeMap之后 - 请注意RxJS的catch和Promise catch是相似但不一样的!

const logoutUserEpic = (action$) => action$
  .ofType(LOGOUT_USER)
  .mergeMap(() =>
    Observable.from(graphQl(AuthLogout))
      .mergeMap(() => Observable.of(
        receive(),
        push('/login')
      ))
      .catch((error) => Observable.of(failure(error)))
  )