-1

I am running a hybrid angular application. Most of my services are still on the AngularJS side. I am able to use those in my hybrid application just fine.

export function myServiceFactory(i: any): any {
  return i.get('MyService');
}

export const myServiceProvider = {
  provide: MyService,
  useFactory: myServiceFactory,
  deps: ['$injector']
};

Then in my Angular app module:

  providers: [
    myServiceProvider,
    ...
  ]

This work great when running the application. However I run into problems testing any Angular component that uses these AngularJS services.

@Component({
  selector: 'my-component',
  templateUrl: './my-component.html',
  styleUrls: ['./my-component.scss'],
})
export class MyComponent {

  constructor(@Inject(MyService) private myService: any) {} 
  ...
}

Then a simple test to just see if I can create the component:

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

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [MyComponent ]
    })
    .compileComponents();
  }));

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

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

When running the test I get the following error:

No provider for InjectionToken MyService!

I tried looking into using this: https://angular.io/api/upgrade/static/testing/createAngularTestingModule, however in the docs it mentions

This helper is for testing services not Components. For Component testing you must still bootstrap a hybrid app. See UpgradeModule or downgradeModule for more information.

However digging into UpgradeModule and downgradeModule, there is really nothing documented on how to bootstrap a hybrid app to test a Component.

Trying to use the provider in test module provides,

TestBed.configureTestingModule({
  declarations: [ObservationListItemComponent ],
  providers: [mapServiceProvider]
})
.compileComponents();

gives the following error:

No provider for $injector!

lostintranslation
  • 23,756
  • 50
  • 159
  • 262

1 Answers1

0

Just like when testing a component that injects an Angular service, you should inject a mock of the AngularJs service using the providers array in the setup test module.

let myMockService = { fakeMethod: () => {} };

TestBed.configureTestingModule({
    declarations: [MyComponent],
    providers: [provide: MyService, useValue: myMockService],
});
g0rb
  • 2,234
  • 1
  • 9
  • 13
  • Sure, but that answer is a bit of a cop out. I get that I can mock, buts lets assume the service just provides some constant values I don't need to mock. If this was an Angular Service it would get injected into the test component just fine, no mock needed. The question revolves around providing the real service to the component during a test. – lostintranslation Apr 29 '21 at 22:40
  • 1
    Then please edit the question to specify that you don't want to mock the service. Mocking a service isn't a "cop out", it's how you would normally test any component. – g0rb Apr 29 '21 at 22:48
  • Only a cop out in terms of the question. I am asking why I am getting an error injecting a AngularJS service into the component when testing. Mocking is just hiding the error. I want to inject the AngularJS service. – lostintranslation Apr 29 '21 at 22:52
  • 1
    Have you tried adding `myServiceProvider` to the providers array in the `configureTestingModule`? – g0rb Apr 29 '21 at 22:56