2

I would like to test get request related functionality. Request should be fired and values mapped to relevant object. Related code is:

it('Should have values set', () => {
  const service: FetcherService = TestBed.get(FetcherService);
  const technologyString = 'technology';
  service.fetchNews(technologyString);
  expect(service.fetchNewsResponse.category === technologyString);
});

Currently it however may not be relevant as relatated test fails with Karma and message is

TypeError: Cannot read property 'category' of undefined

What should I change in code to fix this issue?

edit:

Code related to service.fetchNews is:

public fetchNews(category: string) {
this.httpClient.get<News>('http://localhost:8080/news/' + this.country + '/' + category + '/')
.subscribe(data => this.fetchNewsResponse = data );
}
2
  • Can you post the FetcherService code ? Maybe fetchNews is asynchronous and the assertion is done before fetchNewsResponse is set ? Commented Oct 30, 2018 at 13:57
  • @JuniorDussouillez I added an edit Commented Oct 30, 2018 at 14:01

2 Answers 2

2

Your issues are two-fold. First, you are attempting to read data that has not yet returned (asynchronously) from the server. But more importantly, you are attempting to do an end-to-end test in a unit (or functional) testing environment. Difference between functional test and end-to-end test

For unit testing a service that makes http calls with httpClient, using the HttpClientTestingModule and HttpTestingController give you the greatest flexibility. See the documentation here: https://angular.io/guide/http#testing-http-requests

In your case the final result should look something like this:

describe('FetchNews Service', () => {
    let httpMock: HttpTestingController;
    beforeEach(() => {
        TestBed.configureTestingModule({
            imports: [ HttpClientTestingModule ],
            providers: [ FetcherService ]
        });
        httpMock = TestBed.get(HttpTestingController);
    });
    it('should have values set', async(() => {
        const service: FetcherService = TestBed.get(FetcherService);
        const technologyString = 'technology';
        const responseData = {category: technologyString};
        const country = 'italy';
        service.fetchNews(technologyString);
        let req = httpMock.expectOne('http://localhost:8080/news/' + country + '/technology/');
        expect(req.request.method).toEqual('GET');
        req.flush(responseData); // send responseData as result of the get
        expect(service.fetchNewsResponse.category).toEqual(technologyString); // may need to be tested after observable resolves.
    }));
});
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your answer, I already accepted another one however upvoted this one too.
1

I believe this has something to do with the API's response. Test if you get any error by defining an error handler in your GET request like:

public fetchNews(category: string) {
this.httpClient.get<News>('http://localhost:8080/news/' + this.country + '/' + category 
+ '/')
.subscribe(data => {
this.fetchNewsResponse = data
},
 error => { console.log('Error:', error); }
);
}

1 Comment

Thank you for your answer, at least part of issue was related to fact that Karma's tests were running on different port than application - and server did not had relevant setup for handling this. I also added await delay(2000); related code to test and issue is resolved.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.