[Fixed] Method in Mock service is called but the toHaveBeenCalled() fails in Angular Jasmine

Issue

I’m trying to test if the mock service method is called by method in component.When I used
console.log() inside the method logOut() [Method inside the service] it printed in the console but the
test fails

Method in header.component.ts

onLogOut()

{

 this.authenticationService.logOut(); 

}

File header.component.spec.ts

@Injectable()
class MockAuthService extends AuthenticationService {

user$ = of(new User('R-234', 'Alex', '[email protected]'));

logOut() {
 console.log('Logged Out');
 }
}

describe(‘HeaderComponent’, () => {

let component: HeaderComponent;
let authService: AuthenticationService;
let fixture: ComponentFixture<HeaderComponent>;

beforeEach(async () => {
  TestBed.configureTestingModule({
    declarations: [HeaderComponent],
    imports: [HttpClientTestingModule, RouterTestingModule],
    providers: [HttpClient, AuthenticationService, MockAuthService],
  }).compileComponents();

   TestBed.overrideComponent(HeaderComponent, {
    set: {
      providers: [
         { provide: AuthenticationService, useClass: MockAuthService },
    ],
  },
   });
 });

beforeEach(() => {
   fixture = TestBed.createComponent(HeaderComponent);
   component = fixture.componentInstance;
   fixture.detectChanges();
   authService = TestBed.get(AuthenticationService);
  });


   it('should call logOut method once in the service', fakeAsync(() => {

    let spy = spyOn(authService, 'logOut').and.callThrough();
    component.onLogOut();

    expect(spy).toHaveBeenCalledTimes(1);//this fails
    }));
  });

Solution

Try getting rid of the overrideComponent, I think that could be causing the issue of getting the proper handle of the AuthenticationService.

You should directly useClass in the TestBed for the mock.

let component: HeaderComponent;
let authService: AuthenticationService;
let fixture: ComponentFixture<HeaderComponent>;

beforeEach(async () => {
  TestBed.configureTestingModule({
    declarations: [HeaderComponent],
    imports: [HttpClientTestingModule, RouterTestingModule],
    providers: [HttpClient, AuthenticationService, 
        // add this line
        { provide: AuthenticationService, useClass: MockAuthService }
    ],
  }).compileComponents();

 });

beforeEach(() => {
   fixture = TestBed.createComponent(HeaderComponent);
   component = fixture.componentInstance;
   fixture.detectChanges();
   authService = TestBed.get(AuthenticationService);
  });


   it('should call logOut method once in the service', fakeAsync(() => {

      let spy = spyOn(authService, 'logOut').and.callThrough();
      component.onLogOut();

      expect(spy).toHaveBeenCalledTimes(1);//this fails
    }));
  });

Leave a Reply

(*) Required, Your email will not be published