I am trying to write some unit tests for an application I have been building but I'm running into issues with mocking injections on the various components/services. I've been reading articles and trying various things for a few hours now but so far been unable to find any examples of the correct way to configure the mocks, however I appear to be close...
I have the following code for my test for a DashboardComponent
:
import {
beforeEach,
beforeEachProviders,
describe,
expect,
inject,
injectAsync,
it
} from '@angular/core/testing';
import { provide } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { DashboardComponent } from './dashboard.component';
import { ProjectService } from '../../services/project/project.service';
import { Model3DService } from '../../services/model3D/model3D.service';
class MockProjectService {
public find (model: any): void {}
}
class MockModel3DService {
public get3DModels (): Observable<any> {
return;
}
}
fdescribe('Dashboard Component', () => {
beforeEachProviders(() => {
return [
DashboardComponent,
provide(ProjectService, {
useClass: MockProjectService
}),
provide(Model3DService, {
useClass: MockModel3DService
})
];
});
describe('foo', () => {
it('should do stuff', (inject([DashboardComponent], (dashboardComponent: DashboardComponent) => {
dashboardComponent.easyTest();
expect(dashboardComponent.foo).toEqual('foobar');
})));
});
describe('ngOnInit', () => {
it('should call model3DService.get3DModels on init', (inject([DashboardComponent, Model3DService], (dashboardComponent: DashboardComponent, model3DService: MockModel3DService) => {
dashboardComponent.ngOnInit();
expect(model3DService.get3DModels()).toHaveBeenCalled();
})));
});
});
A couple things to note:
In the examples I've found they extend the real class when they create a mock class. i.e. class MockProjectService {
would be class MockProjectService extends ProjectService {
however that appears to inject the actual class into the component because I then get errors saying I need to inject every service that is injected into ProjectService, and then inject every injection that each of those injections have, so on and so forth. Obviously that isn't what I want as the tests for DashboardComponent
shouldn't care about the actual code behind anything injected into DashboardComponent
or any of its dependencies.
By removing the extends bit of code I was able to get my code to run a simple test where I call a method on DashboardComponent and expect a string to have been updated, it works! I thought I had this nailed, but then I tried to write a test that calls a method on a mocked service, but for some reason the mocked service is empty! :( In the second test above you'll notice I expect model3DService.get3DModels
to have been called, however I get an error that get3DModels is undefined. I console logged the value of model3DService in my component on the line above where it tries to use model3DService.get3DModels
and the log shows me that model3DService is set to MockModel3DService{}
which is missing the method I defined inside MockModel3DService in my test...
How are you all setting up your mocks so you don't have to go down an endless rabbit hole of injections?
Aucun commentaire:
Enregistrer un commentaire