在订阅中使用 return 值对函数进行单元测试

Unit testing a function with return value within subscribe

我有一个函数要进行单元测试,但我不确定如何处理。 简体:

someFunction(): boolean {
 this.service.login().subscribe(response => {
  if (response) {
    return someOtherFunction();
  }
 });
}

someOtherFunction(): boolean {
 this.service.otherTask().subscribe(response => {
  if (response) {
    return true;
  }
 });
}

我想在这种情况下测试someFunction的结果。但是,这不起作用:

describe('someFunction', () => {
  it('returns true', () => {
   serviceSpy.login.and.returnValue(of({response: response}));
   serviceSpy.otherTask.and.returnValue(of({response: otherResponse}));
   result = component.someFunction();
   expect(result).toEqual(true);
 });
});

在此块之前已配置ServiceSpy。 我可以看到函数已执行并且 true 是 returned。但是,目前我要求 result,它仍然是未定义的。测试框架不会等待一切都完成。我尝试过使用 async、fakeAsync、done(),但这些都不起作用。 有没有办法测试 someFunction 的 return 值?

问题出在函数内部,它们 return 的结果在 subscribe 内部,那是行不通的,您需要 return 可观察值或使用局部变量.

someFunction(): Observable<boolean> {
 return this.service.login().pipe(
   first(),
   switchMap(res => res ? this.someOtherFunction() : of(undefined)),
 );
}

someOtherFunction(): Observable<boolean> {
 return this.service.otherTask().pipe(
   first(),
   map(response => !!response),
 );
}

然后在你的测试中你可以做

describe('someFunction', (done) => {
  it('returns true', () => {
   serviceSpy.login.and.returnValue(of({response: response}));
   serviceSpy.otherTask.and.returnValue(of({response: otherResponse}));
   component.someFunction().subscribe(result => {
     expect(result).toEqual(true);
     done();
   });
 });
});

在@satanTime 的回答和评论以及更多互联网搜索的启发下,我编辑了我的代码并进行了如下测试。 someOtherFunction 似乎没有任何订阅问题,所以我在简化中省略了它。

someFunction(): Observable<boolean> {
 return this.service.login().pipe(map(response => {
  if (response) {
    return someOtherFunction();
  }
 }));
}

someOtherFunction(): boolean {
    return true;
}

测试:

describe('someFunction', () => {
  it('returns true', (done) => {
   serviceSpy.login.and.returnValue(of({response: response}));
   serviceSpy.otherTask.and.returnValue(of({response: otherResponse}));
   component.someFunction().subscribe(result => {
   expect(result).toEqual(true);
   done();
   });
 });
});