简体   繁体   中英

How to inject ts-mockito into Angular 4 component test

Similar to this question on typemoq injection, how can I inject ts-mockito objects into angular's TestBed.configureTestingModule() ? Any example ts-mockito tests I can find are independent of angular.

Consider the following minmal working example to test- it contains a ProgressComponent , with a ProgressService on the backend that we're mocking. The service is quite trivial:

import { Injectable } from '@angular/core';

@Injectable()
export class ProgressService {
    private currentState: string = '1';

    constructor() {
    }

    setCurrentState(state: string) {
        this.currentState = state;
    }

    getCurrentState(){
        return this.currentState
    }

}

To mock this without ts-mockito , we simply extend the class.

import {ProgressService} from "../../../progress.service";

export class MockProgressService extends ProgressService{}

And then when testing ProgressComponent , the MockProgressService is passed to the TestBed.

import {async, ComponentFixture, getTestBed, TestBed} from '@angular/core/testing'

import { ProgressComponent } from './progress.component'
import {ProgressService} from "../progress.service"
import {MockProgressService} from "../shared/services/progress/progress.mock";

describe('ProgressComponent', () => {
  let injector: TestBed
  let mockService: ProgressService
  let fixture: ComponentFixture<ProgressComponent>
  let component: ProgressComponent

  beforeEach(async() => {
    TestBed.configureTestingModule({
      declarations: [ ProgressComponent ],
      providers: [{provide: ProgressService, useClass: MockProgressService}]
    }).compileComponents()

    injector = getTestBed()
    fixture = TestBed.createComponent(ProgressComponent)
    component = fixture.componentInstance
    mockService = injector.get(ProgressService)

    fixture.detectChanges();
  });
});

The angular test framework introduces dependency injection through the TestBed . How can we use mockito within angular's test setup? For example, how can the snippet injector.get(ProgressService) be made compatible with ts-mockito mocks?

If a provider should be mocked with another object and not class, it should use useValue or useFactory .

For Jasmine it is:

providers: [{
  provide: ProgressService,
  useValue: jasmine.createSpyObj('ProgressService', [...])
}]

And for ts-mockito it can be:

progressServiceMock = mock(ProgressService);
...
providers: [{provide: ProgressService, useValue: instance(progressServiceMock)}]

While inheriting mocked class frim original class like class MockProgressService extends ProgressService usually doesn't have benefits. If the intention is to mock some methods, they can be mocked with jasmine.spy (or a counterpart that current testing framework has) on real class instance or class prototype. And when a class isn't the one that is tested in current unit test, mocking/stubbing all methods and not several is beneficial for test isolation.

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