I'm stuck on this again and although this thread (MockService still causes error: Cannot read property 'subscribe' of undefined) is exactly about the same thing it still doesn't resolve my problem.
I do have a component which calls a simple function on ngOnInit:
ngOnInit() {
this.getModules();
}
getModules() {
this.configService.getModulesToDisplay().subscribe(modules => {
this.modulesToDisplay = modules;
}
);
}
I want to test two things:
Is getModules
called on ngOnInit
and
Is this.modulesToDisplayed
reassigned when it gets some result
So I mocked my service but the first test still fails with the TypeError 'Cannot read property 'subscribe' of undefined'.
I moved my mocked Service to all different areas since I do guess the mock isn't available when the test starts to build the component. But I still couldn't make it out. My Test looks like:
describe('NavigationComponent', () => {
let component: NavigationComponent;
let fixture: ComponentFixture<NavigationComponent>;
let configServiceMock: any;
beforeEach(async(() => {
configServiceMock = jasmine.createSpyObj('ConfigService', ['getModulesToDisplay']);
configServiceMock.getModulesToDisplay.and.returnValue( of(['module1', 'module2']) );
TestBed.configureTestingModule({
declarations: [
NavigationComponent
],
imports: [
RouterTestingModule,
HttpClientTestingModule
],
providers: [
{ provide: ConfigService, useValue: configServiceMock },
],
schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
}).compileComponents();
beforeEach(() => {
// configServiceMock.getModulesToDisplay.and.returnValue( of(['module1', 'module2']) );
fixture = TestBed.createComponent(NavigationComponent);
component = fixture.componentInstance;
});
}));
I removed fixture.detectChanges() to have full control over when ngOnInit should be called and so my tests look like:
it('should call getModulesToDisplay one time on ngOninit()', () => {
const spyGetModules = spyOn(component, 'getModules');
component.ngOnInit();
expect(spyGetModules).toHaveBeenCalledTimes(1);
});
The first test fails with the Cannot read subscribe error. But the second one passes with the correct mockvalue being used.
it('should assign result to modulesToDisplay', () => {
component.getModules();
expect(component.modulesToDisplay.length).toBeGreaterThan(0);
});
Any hints on what am I still missing are highly appreciated!
getModules
could probably be private, you want to test that it interacts correctly with the test double of the collaborator. Don't call the method directly, only invoke it viangOnInit
, so you have the freedom to refactor within the class. – jonrsharpe