Angular 使用subscribe中的返回值对函数进行单元测试

Angular 使用subscribe中的返回值对函数进行单元测试,angular,observable,karma-jasmine,testbed,Angular,Observable,Karma Jasmine,Testbed,我有一个要进行单元测试的函数,我不知道如何处理它。 简化: someFunction(): boolean { this.service.login().subscribe(response => { if (response) { return someOtherFunction(); } }); } someOtherFunction(): boolean { this.service.otherTask().subscribe(response => {

我有一个要进行单元测试的函数,我不知道如何处理它。 简化:

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。但是,目前我要求的是
结果
,它仍然没有定义。测试框架并不等待一切都完成。我曾尝试使用async、fakeAsync、done(),但这些方法都不起作用。
有没有办法测试
someFunction
的返回值?

问题出在函数内部,它们在
subscribe
内部返回结果,这不起作用,您需要返回一个可观察的或使用局部变量

someFunction():可观察{
返回此.service.login()管道(
第一个(),
switchMap(res=>res?this.someOtherFunction():of(未定义)),
);
}
someOtherFunction():可观察{
返回此.service.otherTask().pipe(
第一个(),
映射(响应=>!!响应),
);
}
然后在你的测试中你可以

description('someFunction',(done)=>{
它('返回真',()=>{
serviceSpy.login.and.returnValue(of({response:response}));
serviceSpy.otherTask.and.returnValue(of({response:otherResponse}));
component.someFunction().subscribe(结果=>{
期望(结果)。toEqual(正确);
完成();
});
});
});

从@satanTime的答案、评论和更多的互联网搜索中获得灵感,我编辑了我的代码和测试,如下所示。
someOtherFunction
似乎没有订阅问题,因此我在简化中省略了它

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

someOtherFunction(): boolean {
    return true;
}

someFunction没有返回值。其他人也不起作用。我很惊讶TypeScript编译器没有对你大喊大叫。我很惊讶它能工作。它似乎做了它需要做的事情。。。某个函数是身份验证守卫的激活物有关系吗?@Century:这是一个糟糕的代码。请重构itI,我无法想象它会像canActivate那样做它需要做的事情。它返回undefined,即false-y,因此路由将永远不会被激活。幸运的是,大多数流量在没有订阅的情况下遵循不同的路径。尽管如此,这部分似乎在某种程度上起了作用。。。我的编译器也没有警告我。无论如何,我让someFunction返回一个可观察的(这对于canActivate来说很好)并返回登录名,但在那里使用管道和映射。我应该把它作为答案发布吗?
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();
   });
 });
});