NullInjectorError:R3InjectorError(DynamicTestModule)[FormBuilder - > FormBuilder]:NullInjectorError:没有FormBuilder的提供者

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

我正在使用 Jasmine 测试我的角度代码。我已经导入了所有内容,但仍然出现错误。这是两个错误:

NullInjectorError:R3InjectorError(DynamicTestModule)[FormBuilder -> FormBuilder]:NullInjectorError:没有 FormBuilder 的提供程序!

期望未定义为真。

这些错误出现在多个组件上。我附上了一个存在这些错误的组件的示例。我该如何解决它? (我是初学者所以请尽量用最简单的方式回答)

app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ReactiveFormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';

import { AppComponent } from './app.component';

import {FormsModule } from '@angular/forms';
import { SortPipe } from './sort.pipe';
import { CustomPipeComponent } from './custom-pipe/custom-pipe.component';
import { CustpipeComponent } from './custpipe/custpipe.component';
import { RideFilterPipePipe } from './ride-filter-pipe.pipe';
import { ReactFormComponent } from './react-form/react-form.component';
import { TemplateDrivenFormComponent } from './template-driven-form/template-driven-form.component';
import { EmailValidator } from './template-driven-form/emailValidator';

@NgModule({
  declarations: [
    AppComponent,
    SortPipe,
    CustomPipeComponent,
    CustpipeComponent,
    RideFilterPipePipe,
    ReactFormComponent,
    TemplateDrivenFormComponent,
    EmailValidator
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule,
    ReactiveFormsModule      
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.spec.ts

import { TestBed } from '@angular/core/testing';
import { ReactiveFormsModule } from '@angular/forms';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';

describe('AppComponent', () => {
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [
        RouterTestingModule,
        ReactiveFormsModule
      ],
      declarations: [
        AppComponent
      ],
    }).compileComponents();
  });

  it('should create the app', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.componentInstance;
    expect(app).toBeTruthy();
  });

  it(`should have as title 'carpool'`, () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.componentInstance;
    expect(app.title).toEqual('carpool');
  });

  it('should render title', () => {
    const fixture = TestBed.createComponent(AppComponent);
    fixture.detectChanges();
    const compiled = fixture.nativeElement as HTMLElement;
    expect(compiled.querySelector('.content span')?.textContent).toContain('carpool app is running!');
  });
});

reactFormComponent.html

<div class="login-comp">
    <div class="container">
        <div class="outer-box">
            <h3 class="title">Reactive form</h3>
            <form [formGroup]="registerForm">
                <div class="form-group">
                    <label class="">Name</label>
                    <input class=" form-control" type="text" formControlName="firstName">
                    <p *ngIf="(registerForm.get('firstName')?.dirty || 
                    registerForm.get('firstName')?.touched ) && 
                    registerForm.get('firstName')?.errors " 
                    class="alert alert-danger">This is required</p>
                </div>
                <div class="form-group">
                    <label class="">email</label>
                    <input class=" form-control" type="email" formControlName="email">
                    <p *ngIf="(registerForm.get('email')?.dirty || 
                    registerForm.get('email')?.touched ) && 
                    registerForm.get('email')?.errors " 
                    class="alert alert-danger">invalid</p>
                </div>
                <div class="form-group">
                    <fieldset formGroupName="address">
                    <label class="">Steet</label>
                    <input class=" form-control" type="text" formControlName="street">
                    <label class="">Zip</label>
                    <input class=" form-control" type="text" formControlName="zip">
                    <label class="">City</label>
                    <input class=" form-control" type="text" formControlName="city">
                </fieldset>
                
                </div>
                <button type="submit" [disabled]="!registerForm.valid" class="btn btn-primary" (click)="subForm()">Submit</button>
                
            </form>
            <div [hidden]="!submittedForm">
                <p>Name: {{registerForm.get('firstName')?.value}}</p>
                <p>Name: {{registerForm.get('email')?.value}}</p>
                <p>Street: {{registerForm.get('address.street')?.value}}</p>
                <p>City: {{registerForm.get('address.city')!.value}}</p>
                <p>zip: {{registerForm.get('address.zip')!.value}}</p>
            </div>
            
        </div>
        
    </div>
</div>

reactFormComponent.ts

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'app-react-form',
  templateUrl: './react-form.component.html',
  styleUrls: ['./react-form.component.css']
})
export class ReactFormComponent implements OnInit {

  registerForm!:FormGroup;
   submittedForm!:boolean;
  constructor(private formBuilder:FormBuilder) {}

  ngOnInit(): void {
    this.registerForm=this.formBuilder.group({
      firstName: ['',Validators.required],
      email: ['', validateEmail],
        address: this.formBuilder.group({
          street:[],
          zip:[], 
          city:['',Validators.required]
        }) 
    });
  }
  subForm() {
    this.submittedForm=true;
    console.log(this.registerForm);
  }
}

function validateEmail(eid:FormControl):any {
  let email_regex=/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
  return email_regex.test(eid.value)?null : {
    emailInvalid: {
      message: 'Invalid Format'
    }
  };
}```
javascript angular angularjs typescript
4个回答
3
投票

该错误表示在

app.component.spec.ts
中创建的测试模块找不到
FormBuilder
的提供程序。

FormBuilder
定义在
FormsModule
中。您会注意到它被导入到
AppModule
中(这就是您的应用程序编译和运行的原因),但它没有被导入到
configureTestingModule
中的
app.component.spec.ts
中。

修复:

describe('AppComponent', () => {
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [
        RouterTestingModule,
        FormsModule,               // << ----- add this line
        ReactiveFormsModule
      ],

1
投票

不是在

app.component.spec.ts
中,而是在
<your-component-name>.spec.ts
中,你必须添加这些:

        imports: [
            FormsModule,
            ReactiveFormsModule,
        ],
        providers: [<your-providers>],
        declarations: [<your-component-name>],

0
投票
describe('AppComponent', () => {
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [
        RouterTestingModule,
        describe('AppComponent', () => {
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [
        RouterTestingModule,
        FormsModule,               // << ----- add this line
        ReactiveFormsModule        // You should add this too
      ],
        

0
投票

这将解决测试中以下代码的问题...

 imports: [
   FormsModule,
   ReactiveFormsModule,
 ],
 providers: [FormBuilder],

但是之后我也遇到了不同的错误

 Error: NG0204: Can't resolve all parameters for FormGroup: (?, ?, ?).

提到this,我后来选择将其包含在我的“tsconfig.spec.json”文件中。我正在使用 Angular 14。看来我需要重构应用程序代码本身,但现在我选择不这样做,而是在测试 tsconfig 文件中设置它。

"extends": "./tsconfig.json",
"compilerOptions": {    
  "useDefineForClassFields": false
},

发布这两个单独的解决方案,因为有些人也可能会遇到这些错误链...希望这有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.