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 );
}
mateuszs
  • 165
  • 1
  • 1
  • 10

2 Answers2

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.
    }));
});
dmcgrandle
  • 5,934
  • 1
  • 19
  • 38
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); }
);
}
Harini P
  • 629
  • 5
  • 12
  • 1
    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. – mateuszs Nov 05 '18 at 16:25