Reputation: 57
I am starting out with unit testing in Angular 9 with Jasmine.
I am testing a simple component which implements ngOnInit
:
export class HomeComponent implements OnInit {
constructor(private router: Router
, private authenticationService: AuthenticationService) { }
ngOnInit(): void {
this.authenticationService.checkIsAuthenticatedObservable()
.subscribe(
(isAuthenicated: boolean) => {
if (isAuthenicated === true) {
this.router.navigate(['/observation-feed']);
}
});
}
}
I am hitting the error with executing the ngOnInIt lifecycle hook:
TypeError: Cannot read property 'subscribe' of undefined
at <Jasmine>
at HomeComponent.ngOnInit (http://localhost:9876/_karma_webpack_/main.js:8140:13)
My test spec is setup like this:
describe('HomeComponent', () => {
let component: HomeComponent;
let fixture: ComponentFixture<HomeComponent>;
let router: Router;
let mockAuthenticationService;
beforeEach(async(() => {
mockAuthenticationService = jasmine.createSpyObj(['checkIsAuthenticatedObservable']);
TestBed.configureTestingModule({
imports: [
RouterTestingModule.withRoutes([
// { path: 'login', component: DummyLoginLayoutComponent },
])
],
declarations: [ HomeComponent ],
providers: [
{ provide: AuthenticationService, useValue: mockAuthenticationService }
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(HomeComponent);
router = TestBed.get(Router);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
mockAuthenticationService.checkIsAuthenticatedObservable.and.returnValue(of(false));
fixture.detectChanges();
// component.ngOnInit();
expect(component).toBeTruthy();
});
});
I have attempted various combinations of setting up the mock object, and calling fixture.detectChanges();
and component.ngOnInit();
at different points in the intialization. None of what I have tried has worked. What's going wrong here?
Upvotes: 1
Views: 6047
Reputation: 949
When you are calling fixture.detectChanges
in the beforeEach
section, Angular runs lifecycle hooks and ngOnInit
is called. This is why you're getting error - you are mocking checkIsAuthenticatedObservable
in the test, after the first fixture.detectChanges
.
Move your mock to the beforeEach
section, before fixture.detectChanges
and it will work correctly.
Also, with Angular 9, you should use TestBed.inject
instead of TestBed.get
which is now deprecated.
beforeEach(() => {
fixture = TestBed.createComponent(HomeComponent);
router = TestBed.inject(Router);
component = fixture.componentInstance;
mockAuthenticationService.checkIsAuthenticatedObservable.and.returnValue(of(false));
fixture.detectChanges();
});
it('should create', () => {
fixture.detectChanges();
expect(component).toBeTruthy();
});
Upvotes: 8