【问题标题】:Angular 4 unit test service calling http serviceAngular 4单元测试服务调用http服务
【发布时间】:2018-02-05 20:33:20
【问题描述】:

我有一个正在调用 http 函数的服务:

processLogin(info) {
    return this._call.post('login', info).subscribe(response => {
        if (response.status === 'success') {
            this._auth.login(response.object);
            return true;
        }

        return false;
    }, error => {
        return false;
    });
}

这是我正在尝试进行的测试:

describe('Facebook Login', () => {
    let service: FacebookLoginService;
    let call: CallService;

    beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [
                FacebookLoginService,
                { provide: CallService, useClass: CallServiceMock },
            ]
        });

        service = TestBed.get(FacebookLoginService);
        call = TestBed.get(CallService);
    });

    it('should process the login when the post method return success', () => {
        spyOn(call, 'post').and.returnValue(Observable.of({status: 'success'}));

        service.processLogin('any').subscribe(response => {
            console.log(response);
        });
    });
});

但是,当我运行测试时,我不断收到错误消息

processLogin().subscribe( ... ) 不是函数

如果我将模拟的响应类型更改为 Observable.of 以外的任何内容,我会收到错误消息

call.post.subscribe( ... ) 不是函数

为什么不工作?我在另一个服务上进行了非常相似的测试,该服务也调用了call.post(),它正在工作。

【问题讨论】:

    标签: angular unit-testing


    【解决方案1】:

    processLogin 返回的不是 observable 而是订阅,因此不会有 subscribe 方法。 subscribe 回调中的返回值被忽略,因此 processLogin 不会按预期工作。

    它可能应该改为返回一个 observable:

    return this._call.post('login', info).map(response => { ... });
    

    然后可以这样测试:

    spyOn(_call, 'post').and.returnValue(Observable.of({ status: 'success' }));
    
    const login$ = service.processLogin('any');
    expect(_call).toHaveBeenCalledWith('login', 'any');
    
    login$.subscribe(response => {
      expect(response).toBe(...);
    }, err => { throw err });
    

    它还需要模拟_auth

    【讨论】:

    • 通过这些更改,测试现在有了 subscribe 方法,但实际的 processLogin 方法永远不会执行。我认为这是因为它缺少subscribe()
    • 在测试中使用 login$.subscribe 订阅。如果您的意思是它在应用程序中无法按预期工作,那么是的,您需要在使用它的任何地方添加subscribe
    • 我只是不明白如何让它工作。因为如果我不使用 .subscribe() 该方法永远不会执行。但是,如果我这样做,那么测试将失败,正如您在答案中所解释的那样。我应该对该方法进行哪些更改以使两者都正常工作?
    • 您需要将processLogin方法中的subscribe字替换为map字。然后,您需要确保将subscribe(...) 添加到您在应用程序中使用processLogin 的每个地方,因为它是可冷观察的。
    • 哦..好的。我在想这与自己的方法有关。我得到它。现在它正在工作。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-06
    • 1970-01-01
    • 2020-03-17
    • 1970-01-01
    • 2017-06-03
    • 1970-01-01
    • 2022-06-10
    相关资源
    最近更新 更多