Angular 6 unit testing a http get request

Bálint Réthy

I have a component where I have a request in a function like:

getData():Observable<any>{
    return this._http.get('/app/data', {observe: 'response'});
}

It returns me an object array in subscription like:

[{name: 'a'}, {name: 'b'}]

or something similar.

I wanted to write a test that makes sure getData() calls http GET once with the proper url and the subscription returns something array-like.

My code:

...
    it('getData() should http GET names', () => {
        inject([HttpTestingController], (httpMock: HttpTestingController) => {

          const names = [{name: 'a'}, {name: 'b'}];

          component.getData().subscribe((res) => {
            expect(res).toEqual(names);
          });

          const req = httpMock.expectOne('/app/data');
          expect(req.request.method).toEqual("GET");
          req.flush(names);

          httpMock.verify();
        });
      });
...

I failed the test with this message: "Expected no open requests, found 1: GET /app/data"

Lucho

First off for good practices you should separate your component from making the request itself and use a Service instead as you will find it more cleaner in the longer run as your app grows for services to handle API requests.

This is another approach you can do for getting it to work with the HttpTestingController as I'm not quite sure why your inject of the controller is not working.

simply test the service instead or just structure your component the same approach on your component tests with this workaround.

get your data from the service by injecting it to the component.

Component:

@Component({
  selector: 'app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  constructor(private service: TestService)
}

Service:

@Injectable()
export class TestService {

  constructor(private http: HttpClient) { }

  getData(): Observable<any>{
    return this.http.get('/app/data');
  }

}

then test the service in this way instead, it's just as your component test but just using the service instead

Test:

describe('TestService', () => {

  let httpMock: HttpTestingController;
  let testService: TestService;

  beforeEach(() => {

    TestBed.configureTestingModule({
        imports: [ HttpClientTestingModule ],
        providers: [ TestService ]
    });

    testService = TestBed.get(TestService);
    httpMock = TestBed.get(HttpTestingController);

  });

  it('getData() should http GET names', () => {

    const names = [{name: 'a'}, {name: 'b'}];

    testService.getData().subscribe((res) => {
      expect(res).toEqual(names);
    });

    const req = httpMock.expectOne('/app/data');
    expect(req.request.method).toEqual("GET");
    req.flush(names);

    httpMock.verify();
  });

});

here is the test in action

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related