简体   繁体   中英

How to dependency inject interface in angular 6 unit test

One of the service dependency injects an interface in the constructor. I wonder, how I can dependency injects the interface in the unit test?

Exported interface:

export interface MobilePlatform {
  onClick(): void;
  onPageFinished(router: Router): void;
  onPageStart(): void;
  sendClose(): void;
  tts(text: String): void;
}

Service injects the interface in the constructor

constructor(private platform: MobilePlatform, private router: Router) {}

How I can inject this interface in the angular unit test?

describe('MobileActions', () => {
  let actions: MobileActions;
  let platform: MobilePlatform;

  beforeEach(() => {

    TestBed.configureTestingModule({
      providers: [
        MobileActions,
        { provide: MobilePlatform, useClass: MockMobilePlatform },
        { provide: Router, useClass: MockRouter }
      ]
    });

    actions = TestBed.get(MobileActions);
    platform = TestBed.get(MockMobilePlatform);
  });

  it('should create actions', () => {
    expect(actions).toBeTruthy();
    expect(platform).toBeTruthy();
  });
});

Seems this kind of inject failed.

You can't, since an interface is a contract that does not get transpiled to an actual class function. In order to create a testable representation of such interface in the Angular injector, you will want to create a typed injection token:

Somewhere in your MobilePlatform models file:

export const MOBILE_PLATFORM = new InjectionToken<MobilePlatform>('mobilePlatform');

Then in your service constructor:

constructor( @Inject(MOBILE_PLATFORM) private platform: MobilePlatform, private router: Router ) {}

Finally, in the providers array of your testing module:

{ provide: MOBILE_PLATFORM, useClass: MockMobilePlatform },

I couldn't achieve this using TestBed, instead I use mock classes like this

class MobilePlatformMockClass implements MobilePlatform {
    // implement interface mock functions
}

describe('MobileActions', () => {
  let actions: MobileActions;
  let platform: MobilePlatform;

  beforeEach(() => {
    const mobilePlatformMock = new MobilePlatformMockClass();
    const routerMock = { navigate: () => {} };
    actions = new MobileActions(mobilePlatformMock, routerMock)
  });

  it('should create actions', () => {
    expect(actions).toBeTruthy();
  });
});

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