0

I have the same set up as this post https://stackoverflow.com/a/42462579/1818048

But i am unable to use the ServiceLoctor.inject.get in my Karama Jasmine tests - the injector is null

  constructor() {
    this.inject = ServiceLocator.injector.get(InjectionService);
    this.configService = ServiceLocator.injector.get(ConfigService);
}

In the app.moudle module i declared the following so that it is globally available.

export class AppModule {
  constructor(private injector: Injector) {
    ServiceLocator.injector = this.injector;
  }
}

Here is a snippet from my test setup

describe('MyButtonComponent', () => {
  let component: MyButtonComponent;
  let fixture: ComponentFixture<MyButtonComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ButtonComponent, MyButtonComponent],
      providers: [SomeService,
        { provide: Router, useClass: RouterTestingModule },
        { provide: ServerService, useClass: GenericMock },
      ]
    })
      .overrideComponent(ResourceService, {
        set: {
          providers: [
            { provide: ConfigService, useClass: ConfigServiceMock }
          ]
        }
      })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(MyButtonComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

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

});

Now when i run the test ServiceLocator.injector is null. How can i make Karma Jasmin set this in the parent or is this not possible?

Estus Flask
  • 206,104
  • 70
  • 425
  • 565
dale
  • 1,258
  • 2
  • 17
  • 36

2 Answers2

1

@estus yours must a be a different version as for mine the code below worked for me. But you got me off on the right track thanks.

  beforeEach(inject([Injector], (injector: Injector) => {
     ServiceLocator.injector = injector;
  }));
dale
  • 1,258
  • 2
  • 17
  • 36
0

This global injector is a questionable move in Angular because it makes application units depend on other application units (AppModule) and breaks encapsulation.

Basically, it should be done in unit tests manually:

beforeEach(inject(injector: Injector) => {
  ServiceLocator.injector = injector;
}));

And undone afterwards:

afterEach(() => {
  ServiceLocator.injector = null;
});

A better move is to move global injector to separate module, so it could be included in test bed configuration.

Estus Flask
  • 206,104
  • 70
  • 425
  • 565
  • I'm struggling to get this to work. I'm getting all kinds of errors such as ',' expected and Cannot find name 'injector' and Argument of type '{ ServiceLocator: any; }' is not assignable to parameter of type 'number'. – dale Aug 24 '17 at 07:06