NX Angular 单元测试因 NullInjectorError 而失败

问题描述 投票:0回答:1

我尝试在我的应用程序中使用 Angular 注入令牌,但它一直导致我的单元测试失败。

这是一个演示该问题的存储库:

https://github.com/shadow1349/nx-filereplacementissue/tree/main

如果您检查主分支,请运行

npm install
,然后运行
npx nx run test:test
您将看到以下错误:

NullInjectorError: R3InjectorError(Standalone[ComponentsComponent])
[InjectionToken TEST_INJECTION_TOKEN -> InjectionToken TEST_INJECTION_TOKEN -> InjectionToken TEST_INJECTION_TOKEN]:
NullInjectorError: No provider for InjectionToken TEST_INJECTION_TOKEN!

这是我的注入令牌:https://github.com/shadow1349/nx-filereplacementissue/blob/main/shared/injection-tokens/src/index.ts

export const TEST_INJECTION_TOKEN = new InjectionToken<BehaviorSubject<string>>(
  'TEST_INJECTION_TOKEN'
);

我的应用程序配置,位于此处:https://github.com/shadow1349/nx-filereplacementissue/blob/main/test/src/app/app.config.ts

import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { appRoutes } from './app.routes';
import { TEST_INJECTION_TOKEN } from '@test-filereplacements/injection-tokens';
import { BehaviorSubject } from 'rxjs';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(appRoutes),
    {
      provide: TEST_INJECTION_TOKEN,
      useValue: new BehaviorSubject<string>('Hello World'),
    },
  ],
};

然后我有一个共享组件导入到我的应用程序组件中,称为 ComponentsComponent,位于此处:

https://github.com/shadow1349/nx-filereplacementissue/blob/main/test/src/app/app.component.ts

这里:

https://github.com/shadow1349/nx-filereplacementissue/blob/main/shared/components/src/lib/components/components.component.ts

// app component
import { Component } from '@angular/core';
import { RouterModule } from '@angular/router';
import { NxWelcomeComponent } from './nx-welcome.component';
import { ComponentsComponent } from '@test-filereplacements/components';

@Component({
  standalone: true,
  imports: [NxWelcomeComponent, RouterModule, ComponentsComponent],
  selector: 'test-filereplacements-root',
  templateUrl: './app.component.html',
  styleUrl: './app.component.scss',
})
export class AppComponent {}

//components.component.ts
import { Component, Inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { TEST_INJECTION_TOKEN } from '@test-filereplacements/injection-tokens';
import { BehaviorSubject } from 'rxjs';

@Component({
  selector: 'test-filereplacements-components',
  standalone: true,
  imports: [CommonModule],
  templateUrl: './components.component.html',
  styleUrl: './components.component.css',
})
export class ComponentsComponent {
  constructor(
    @Inject(TEST_INJECTION_TOKEN) public testToken: BehaviorSubject<string>
  ) {
    console.log('testToken', this.testToken);
  }
}

当您运行时,这一切都正常工作

npx nx run test:serve --configuration=development
它会很好地控制台日志。

这就是您会遇到问题的地方。如果您使用 Jest 运行测试,它将通过。但是,当您运行

npx nx run test:test
时,它会失败并显示:

NullInjectorError: R3InjectorError(Standalone[ComponentsComponent])
[InjectionToken TEST_INJECTION_TOKEN -> InjectionToken TEST_INJECTION_TOKEN -> InjectionToken TEST_INJECTION_TOKEN]:
NullInjectorError: No provider for InjectionToken TEST_INJECTION_TOKEN!

我知道您要问的第一个问题是,在 app.component.ts 中我是否有注入令牌的提供者,是的,我有。你可以在这里看到:

https://github.com/shadow1349/nx-filereplacementissue/blob/main/test/src/app/app.component.spec.ts

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AppComponent } from './app.component';
import { NxWelcomeComponent } from './nx-welcome.component';
import { RouterTestingModule } from '@angular/router/testing';
import { TEST_INJECTION_TOKEN } from '@test-filereplacements/injection-tokens';
import { BehaviorSubject } from 'rxjs';

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

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [AppComponent, NxWelcomeComponent, RouterTestingModule],
      providers: [
        {
          provide: TEST_INJECTION_TOKEN,
          useValue: new BehaviorSubject<string>('Hello World'),
        },
      ],
    }).compileComponents();

    fixture = TestBed.createComponent(AppComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

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

但是,它仍然认为注入令牌不存在。有谁知道为什么吗?

谢谢!

angular dependency-injection jestjs nrwl-nx nx-monorepo
1个回答
0
投票
NullInjectorError: R3InjectorError(Standalone[ComponentsComponent])
[InjectionToken TEST_INJECTION_TOKEN -> InjectionToken TEST_INJECTION_TOKEN -> InjectionToken TEST_INJECTION_TOKEN]:
NullInjectorError: No provider for InjectionToken TEST_INJECTION_TOKEN!

要修复此错误,您需要在组件中提供 InjectionToken,如下所示:

@Component({
  selector: 'test-filereplacements-components',
  standalone: true,
  imports: [CommonModule],
  templateUrl: './components.component.html',
  styleUrl: './components.component.css',
  providers: [
    {
      provide: TEST_INJECTION_TOKEN,
      useValue: new BehaviorSubject<string>('Hello World'),
    },
  ]
})
export class ComponentsComponent {
  constructor(
    @Inject(TEST_INJECTION_TOKEN) public testToken: BehaviorSubject<string>
  ) {
    console.log('testToken', this.testToken);
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.