Rxjs 如何测试在.finally()中执行的代码

Rxjs 如何测试在.finally()中执行的代码,rxjs,Rxjs,最后按说明工作 如何测试最终运行的代码 // code function doCall(body) { isWaitingForRequestToComplete(); return this.apiService .someRequest(body) .map(response => transform(response)) .catch(error => Observable.of('Request failed: ' + error.messag

最后
按说明工作

如何测试最终运行的代码

// code
function doCall(body) {
  isWaitingForRequestToComplete();
  return this.apiService
    .someRequest(body)
    .map(response => transform(response))
    .catch(error => Observable.of('Request failed: ' + error.message))
    .finally(() => {
      requestHasCompleted()
      console.log("Finally");
    });
}

// unit test
it('test observable', () => {
  const testBody = {};
  doCall(testBody).subscribe(() => {
    expect(isWaitingForRequestToComplete).toHaveBeenCalled();
    expect(apiService.someRequest).toHaveBeenCalled();
    console.log("Finally should have been executed");
    expect(requestHasCompleted).toHaveBeenCalled();
  });
});
输出为:

# Finally should have been executed
# Finally
# expect spy requestHasCompleted to have been called

因此,在执行
subscribe(next)
之后调用finally,这很有意义。把期望值放在completed中:
订阅(下一步,错误,完成)
,也没有帮助。

Lol,autocomplete给了我答案。 一时兴起,我在
订阅()后加了一个
,看看订阅后是否有处理程序,并得到了以下建议:
.add、.closed、.remove、.unsubscribe

.add(函数)添加一个下拉列表,在取消订阅()期间调用该下拉列表

以…为例

虽然我不太明白是什么触发了
unsubscribe()
()。
我一直认为订阅一直存在,直到它们被明确地从…

取消订阅为止,因为您正在使用
it(…)
进行测试,我假设您正在使用
jasmine
mocha
来测试异步函数

it('test observable', done => {
  this.apiService
    .someRequest(...)
    .map(...)
    .finally(done)
    .subscribe();
})

注意,我使用了
.finally(done)
告诉测试环境此方法何时正确结束。如果我没有调用
done()
测试将在超时时失败。

文档非常清楚,
subscribe
仍然是必需的。“我一直认为订阅只会一直存在,直到它们被明确取消订阅…”不,它没有。例如,看一看
大理石。它发出它必须发出的信息,并在最后一个值之后立即完成。@最大化,因此在
完成
事件后自动取消订阅。。。也有道理。如果有一些文档可以解释可观察的生命周期,那就太好了。我没有因为超时而导致测试失败的问题,但是关于将
expect()
查询放在哪里,这样
finally()
中的代码就已经执行了<代码>完成
解决了一个我没有的问题。这就是重点。您不需要使用
expect
来检查是否执行了
finally()
。这就是
done
的目的。此外,如果可观察链是异步的(例如,如果使用了
delay
操作符),则不能使用
expect
it('test observable', done => {
  this.apiService
    .someRequest(...)
    .map(...)
    .finally(done)
    .subscribe();
})