First, I apologize. I'm really new to Angular and am not sure I know enough to ask a good question, let alone provide some small working examples.
I'm trying to use spyOn in a unit test, and not having much luck.
Basically, my unit test calls a method on component that calls a service1, that calls another service2.
When I try to spyOn on service1, it doesn't use the mock value that I provide. It calls the "real" ServiceProvidersHTTPService.getAllUsers and uses AppConfigService instead of MockAppConfigService.
I'll start by copying my Test.
describe('ProjectAnalystComponent', () => {
let component: ProjectAnalystComponent;
let fixture: ComponentFixture<ProjectAnalystComponent>;
let service: ServiceProvidersHTTPService ;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [HttpClientModule, RouterTestingModule],
declarations: [ ProjectAnalystComponent ],
providers:
[
ServiceProvidersHTTPService,
CurrentCreateProjectService,
NotificationService,
MessageService,
ProjectLeadAnalystHTTPService,
ExceptionService,
{provide: AppConfigService, useClass: MockAppConfigService }
],
schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ProjectAnalystComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
console.log("######### Did this run");
let service = fixture.debugElement.injector.get(ServiceProvidersHTTPService);
spyOn(service, 'getAllUsers').and.returnValue('{}');
expect(component).toBeTruthy();
});
});
TL;DR Mock your service.
In your testbed, you provide the actual service :
providers:[ServiceProvidersHTTPService, ...
This means you actually call the real methods of your service .
If you mock your service, like you did there :
{provide: AppConfigService, useClass: MockAppConfigService }
Then you call random functions that you declare in your mock .
Another advantage of mocking, you get rid of the dependencies of your dependencies.
As you said, your service calls another service : if you mock your first service, you don't have to add the dependencies of this service into your testbed .
So, they way to go :
const mock = {
provide: ServiceProvidersHTTPService,
useValue: {
getAllUsers: () => null
}
};
In your testbed now :
providers: [mock, ...
In useValue
, you must put all the variables and all the functions of your actual service, and mock them .
In this case, instead of making HTTP calls, your function getAllUsers
will simply return null. You can make it return anything you want (the good practice is to return a value that is the same type of the value that should be returned).
Last piece of advice : your unit tests should test only the functions and methods of your actual feature (here being ProjectAnalystComponent
). You should not test if your service call the other service here : you should test that in the unit testing of your service .
If you have any questions, feel free to ask !
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.