James
James

Reputation: 2860

Testing a service method with an HTTP request in Angular 6

I am having an issue with one of my unit tests whereas a function that contains an HTTP post request is not returning a string when it should be. Here is the service function in question:

public getAnonToken(prev?: string): string {
        if (this.tokens[prev]) {
            return this.tokens[prev]
        }

        if(prev) {
            this.tokens[prev] = prev;
        }        

        this.http.post<any>(HttpUrl.ANON_TOKEN, {})
            .subscribe((response) => {
                this.saveAuthToken(response.data);
                this.tokens[prev] = response.data;

                // analytics!!!
                // Global.internalAnalytics.getAnonToken();
                return response.data;
            });            
    }

As you can see, a request made to the token generation endpoint which returns an observable which I then subscribe to and return the token from the getAnonToken() function.

Here is my test:`

fit("should call the token endpoint and save then return a new token if old token has expired", () => {
    const mockTokenResponseData = {
        data: "i am a token"         
    }
    spyOn(httpClient, "post").and.returnValue(Observable.of(mockTokenResponseData));

    expect(authService.getAnonToken()).toEqual("i am a token");        

});`

As you can see, I am creating a mock response (an observable) and then setting it as the return value when the post request is made using a spy. Instead of 'i am a token' I get undefined. I have a feeling this is because the test is not waiting for the observable to return but I am unsure as to how this is resolved. Can anyone see what is happening here? thanks

Upvotes: 1

Views: 2866

Answers (1)

Castro Roy
Castro Roy

Reputation: 7823

You are missing returning the this.http.post in your function, also, you need to put your expect into the subscription.

Return the call to http.post

return this.http.post<any>(HttpUrl.ANON_TOKEN, {})
    .subscribe((response) => {
        this.saveAuthToken(response.data);
        this.tokens[prev] = response.data;

        // analytics!!!
        // Global.internalAnalytics.getAnonToken();
        return response.data;
    });            

Please, not the return in front of this.http.post

Put the expect inside the subscription

authService.getAnonToken().subscribe((data) => {
    expect(data).toEqual("i am a token");
});

Hope it helps

Upvotes: 2

Related Questions