简体   繁体   中英

How do I mock a service dependency in Angular with Jasmine?

I've been googling this for a while and there's no quick concise answer to something that I'd consider pretty trivial.

I have a service serviceToTest , which has a dependency serviceDep which is injected via Angular's DI.

The service looks something like this

export class ServiceToTest {
    constructor(private _dep: ServiceDep){}

    serviceMethod() {};
}

I want to unit test the serviceMethod method, and to do that I need to instantiate the service and mock the dependency. The dependency doesn't need to do anything other than allow the instantiation of the service. The method I want to test doesn't require the dependency to be executed.

How can I set up a mock so that I can satisfy the service's constructor?

You can provide your own mock service in place of the actual service:

describe('ServiceToTest ', () => {
  beforeEach(() => TestBed.configureTestingModule({
    imports: [],
    providers: [{ provide: ServiceToTest, useClass: ServiceToTestMock }]
  }));

Some options below.

Option one :

The Angular recommended way to do this is via spies :

it('should return value', () => {
  const serviceDepSpy = spyOn(Testbed.inject(ServiceDep), 'serviceMethod').returnValue(of(MOCK_VALUE));

  component.ngOnInit(); // assuming your method is called on init. 

  expect(serviceDepSpy).toHaveBeenCalled();
});

I quote:

Prefer spies as they are usually the easiest way to mock services.

This allows you to mock easily at the unit test level (in each of your tests) and avoid overriding the mocked service (if you go with a useClass approach this can easily become an issue.

Option two :

useClass

This tends to work best when you will always return the same value in each of your test cases. If you need different mock values in each test, I'd go with spies.

Option three

useValue This works best when you need to hard code a value or imported mock object and use the same mock value in all test cases. Like useClass it can be tricky to override.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM