Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 9 TestBed.inject & Provider Overrides

When using provider overrides what is the alternative of the following now that TestBed.get has been deprecated in Angular 9

TestBed.configureTestingModule({
  providers: [{ provide: MyClass, useClass: MyStub}]
});

const obj : MyStub = TestBed.get(MyClass);

Is it really this or is there a better way?

const obj : MyStub = TestBed.inject(MyClass) as unknown as MyStub;
like image 466
C. Rodwell Avatar asked Feb 18 '20 12:02

C. Rodwell


People also ask

What is TestBed inject?

TestBed. configureTestingModule() helps you configure the providers. Configuring the providers means you are letting the Angular dependency injection system know about this dependency which later it can inject in to components when requested through a dependency injection token.

How do you inject a service in Spec TS file?

For inject a service into spec file, you have to add TestBed configuration and register your service in provider array same as module ts file. Show activity on this post. This answer assumes you want to unit test the component.

What does TestBed do in Angular?

TestBedlink. Configures and initializes environment for unit testing and provides methods for creating components and services in unit tests.

How do you inject service in unit testing?

The TestBed provides methods for creating components and services in unit tests. The TestBed methods are inject() , configureTestingModule() etc. To inject a service, we use TestBed. inject() method.

How do I inject a service inside a test in angular?

Then inject it inside a test by calling TestBed.inject () with the service class as the argument. Note: TestBed.get () was deprecated as of Angular version 9. To help minimize breaking changes, Angular introduces a new function called TestBed.inject (), which you should use instead.

What is testbed in angular?

Description link. TestBed is the primary api for writing unit tests for Angular applications and libraries. Note: Use TestBed in tests. It will be set to either TestBedViewEngine or TestBedRender3 according to the compiler used.

How do I test a @ngmodule in testbed?

The TestBed.configureTestingModule () method takes a metadata object that can have most of the properties of an @NgModule. To test a service, you set the providers metadata property with an array of the services that you'll test or mock.

What is angular dependency injection testing?

Angular testing utilities make it straightforward to investigate how injected services behave. Your application relies on Angular dependency injection (DI) to create services. When a service has a dependent service, DI finds or creates that dependent service.


2 Answers

For all intents and purposes, your MyStub should at least be a Partial or a class that extends the class it's trying to mock, otherwise your tests are kinda 'wrong', so if that's the case you can just do:

const obj = TestBed.inject(MyClass);

If you somehow will have different properties or different function signatures on your stub, you can also do this:

const obj = TestBed.inject<MyStub>(MyClass as any);

But generally speaking, your mocks should (partially) share the same signature as the thing it's mocking, which also means there is no need for casting

like image 140
Poul Kruijt Avatar answered Oct 17 '22 16:10

Poul Kruijt


let valueServiceSpy: jasmine.SpyObj<ValueService>;

beforeEach(() => {
  const spy = jasmine.createSpyObj('ValueService', ['getValue']);

  TestBed.configureTestingModule({
    providers: [
      { provide: ValueService, useValue: spy }
    ]
  });
  // This is new way to inject Spied Service
  valueServiceSpy = TestBed.inject(ValueService) as jasmine.SpyObj<ValueService>; 
});

and then in tests

it('#getValue should return stubbed value from a spy', () => {
  valueServiceSpy.getValue.and.returnValue(yourValue);
  ...
});

Ref

like image 1
Bhavin Avatar answered Oct 17 '22 16:10

Bhavin