Angular Standalone Component - No provider for InjectionToken

687 views Asked by At

I have a standalone component using a Injection Token. This token help me to set a path (using micro-fontend the path is not the same for all of them). I'm not providing this token in my component because I need to override it using providers in my app-module.ts.

So my component have this constructor:

constructor(
    @Inject(ICON_SVG_PATH) public iconSvgPath: string,
    private readonly renderer: Renderer2
  ) {}

When I use my component, I can just import my component and provide my token in the providers. For example, this is what I do in storybook:

imports: [IconComponent],
providers: [
   {
       provide: ICON_SVG_PATH,
       useValue: '/assets/icons',
   },
],

My problem is when I try to write the test for this component in my spec.ts file, I have this error:

NullInjectorError: R3InjectorError(Standalone[IconComponent])[InjectionToken ICON_SVG_PATH -> InjectionToken ICON_SVG_PATH -> InjectionToken ICON_SVG_PATH]: NullInjectorError: No provider for InjectionToken ICON_SVG_PATH! error properties: Object({ ngTempTokenPath: null, ngTokenPath: [ 'InjectionToken ICON_SVG_PATH', 'InjectionToken ICON_SVG_PATH', 'InjectionToken ICON_SVG_PATH' ] })

First of all, I tried to provide my Token like I do when I use it:

await TestBed.configureTestingModule({
      imports: [IconComponent],
      providers: [
        {
          provide: ICON_SVG_PATH,
          useValue: '/assets/icons',
        },
      ],
    })
      .overrideComponent(IconComponent, {
        set: { changeDetection: ChangeDetectionStrategy.Default },
      })
      .compileComponents();

But I have the same error.

I also tried to provide it like that:

TestBed.overrideProvider(MY_INJECTION_TOKEN, { useValue: {} });

But I have the same result.

Finally, I tried to provide it from the test.ts file but nothing more happened.

getTestBed().initTestEnvironment(
    BrowserDynamicTestingModule,
    platformBrowserDynamicTesting([
        {
            provide: MY_INJECTION_TOKEN,
            useValue: {},
        },
    ])
);

Thanks

1

There are 1 answers

5
Tony Ngo On

Did you already put your config inside beforeEach ?

beforeEach(waitForAsync(() => {
   TestBed.configureTestingModule({
      imports: [IconComponent],
      providers: [
        {
          provide: ICON_SVG_PATH,
          useValue: '/assets/icons',
        },
      ],
    })
      .overrideComponent(IconComponent, {
        set: { changeDetection: ChangeDetectionStrategy.Default },
      })
      .compileComponents();
  }));