angularunit-testingjasmineinjectangular14

How to unit test a function that uses the new Angular 14's "inject" function?


I've created a function that utilizes that new Angular 'inject' function. Since the inject function can be used only when initializing a class (or factory) that is part of the dependency injection tree, this function is meant to be used in the constructor of a component / service.

I want to unit test this function with mock dependencies. The problem is I can't just call it in unit tests, because it will be called in an incorrect context. I can create a component / service just for the unit test purposes but it feels like too much boilerplate to test a simple function.

Is there a recommended way of doing this?


Solution

  • You can use runInInjectionContext for this, take for example testing an Angular HTTP interceptor that prohibits access based on a configuration service. You first set up your test bed as you would do with components:

    beforeEach(() => {
      TestBed.configureTestingModule({
        providers: [
          {
            provide: ConfigurationService,
            useFactory: () => createSpyObj(ConfigurationService, ['getEnvironmentVariable'])
          },
        ]
      })
    });
    

    Then you can write your tests and execute your function that requires injection inside the runInInjectionContext callback as such:

    it('should prohibit http', () => {
      const config: any = TestBed.inject(ConfigurationService);
      config.allowHttp.and.returnValue(false)
      const fakeHttpRequest = {url: 'http://www.test.be'} as HttpRequest<unknown>;
      TestBed.runInInjectionContext(() => {
        authHttpInterceptor(fakeHttpRequest, null).subscribe((response) => {
          expect(response.statusCode).toBe(505)
        })
      })
    })