Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test if a service is called from the component in angular

I have a component which on init calls getAllUsers() method and getAllUsers() calls getAllUsersApi from my service. I want to test if both the calls are actually made.

Here are some snippets from my code:

test.component.ts

ngOnInit(){
  this.getAllUsers();
}
getAllUsers(){
   this.userService.getAllUsersApi('');
}

test.service.ts

getAllUsersApi(){
   return this.http.get('api/endpoint')
}

test.service.spec.ts

it('should call getAllUsers method on init'){
  spyOn(userService, 'getAllUsersApi');
  spyOn(component, 'getAllUsers');
  component.ngOnInit();
  expect(component.getAllUsers).toHaveBeenCalled();
  expect(userService.getAllUsersApi).toHaveBeenCalled(); // it fails here
}

But it fails here: expect(userService.getAllUsersApi).toHaveBeenCalled();

Can anyone please help me what I am doing wrong.

like image 426
undefined Avatar asked Feb 13 '19 11:02

undefined


People also ask

How do I unit test a service with Angular components?

Mock Service Dependency In Angular For unit testing the method, you need to mock the service method getPosts to test the component method. Let's start by writing unit test for testing method getPostDetails when the response from service method getPosts is an empty array. Add the following unit test case to the app.

How do you test a service with dependencies?

Angular services can be tested in a couple of different ways, two most prominent being isolated tests and using the Angular TestBed . However, things get interesting when the service under test has dependencies (injected using Angular's dependency injection).

What is TestBed in Angular testing?

TestBed is the primary api for writing unit tests for Angular applications and libraries. Note: Use TestBed in tests. It will be set to either TestBedViewEngine or TestBedRender3 according to the compiler used.

What is used to inject a service into a test function?

To test a service, you set the providers metadata property with an array of the services that you'll test or mock. content_copy let service: ValueService; beforeEach(() => { TestBed. configureTestingModule({ providers: [ValueService] }); }); Then inject it inside a test by calling TestBed.


1 Answers

The reason your test fails, is because your component spy componentSpy is actually replacing your getAllUsers function in your component with an empty stub and therefore your getAllUsersApi call will never happen. and.callThrough will set up a spy and make sure the original function is being called.

I would test it like this:

it('should call getAllUsers method on init', () => {
  // set up spies, could also call a fake method in case you don't want the API call to go through
  const userServiceSpy = spyOn(userService, 'getAllUsersApi').and.callThrough();
  const componentSpy = spyOn(component, 'getAllUsers').and.callThrough();

  // make sure they haven't been called yet
  expect(userServiceSpy).not.toHaveBeenCalled();
  expect(componentSpy).not.toHaveBeenCalled();

  // depending on how your component is set up, fixture.detectChanges() might be enough
  component.ngOnInit();

  expect(userServiceSpy).toHaveBeenCalledTimes(1);
  expect(componentSpy).toHaveBeenCalledTimes(1);
});
like image 144
Fabian Küng Avatar answered Nov 15 '22 04:11

Fabian Küng