单元测试使用RxJs主题的Angular2服务

时间:2017-02-24 13:45:41

标签: unit-testing angular rxjs observable subject

在我的应用程序中,我编写了一个AuthService来处理后端服务授权。为了通知组件有关新登录状态的信息,我使用了一个更新其订阅者的BehavourSubject。这是(简化)代码:

@Injectable()
export class OAuth2Service {

    private authState: BehaviorSubject<boolean> = new BehaviorSubject(false);

    login(): void {
        this.authState.next(true);
    }

    public getAuthState(): Observable<boolean> {
        return this.authState.asObservable();
    }
}

现在,我想对该行为进行单元测试,并根据Angular2文档和Ticket编写测试,如下所示:

it('should handle auth state', async(inject([OAuth2Service, TokenDao], (oAuth2Service: OAuth2Service, tokenDao: TokenDao) => {

    return oAuth2Service.getAuthState().toPromise()
        .then((state) => {
            expect(state).toEqual(false);
        });
    })
));

不幸的是,toPromise()永远不会执行then()回调。据我所知,它是因为Observable永远不会完成(按照预期。在整个应用程序生命周期中,身份验证状态可能会发生变化)。 See here

注意:由于BehaviourSubject应默认为false,因此不会调用login()。我修改了测试以调用login()。仍然没有承诺回调。

问题:如何正确测试我的身份验证服务的行为?我错过了什么吗?

1 个答案:

答案 0 :(得分:3)

我的解决方案是避免使用Angular2测试辅助方法。所以我将测试重构为:

it('should handle auth state', (done) => {
    let oAuth2Service: OAuth2Service = TestBed.get(OAuth2Service);
    oAuth2Service.getAuthState().subscribe((state) => {
        expect(state).toEqual(false);
        done();
    });
});

到目前为止,使用Jasmines done()回调做了这个伎俩。