だから私はこのようなものになる子コンポーネントを持っています
_export class ChildComponent implements OnInit {
@Input('parentForm')
public parentForm: FormGroup;
constructor(private fb: FormBuilder, private cd: ChangeDetectorRef) { }
ngOnInit() {
this.parentForm.addControl('newControl', <Some Control>);
}
}
_
次に、私はこのような最小限の単体テストファイルを持っています
_describe('ChildComponent', () => {
let component: ChildComponent;
let fixture: ComponentFixture<ChildComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [ReactiveFormsModule, FormsModule],
declarations: [ ChildComponent ],
providers: [ FormBuilder, FormGroup ]
})
.compileComponents();
}));
beforeEach(inject([FormBuilder], (fb: FormBuilder) => {
fixture = TestBed.createComponent(ChildComponent);
component = fixture.componentInstance;
component.parentForm = fb.group({});
component.ngOnInit();
fixture.detectChanges();
}));
fit('should be created', () => {
expect(component).toBeTruthy();
});
});
_
以前は、parentFormが未定義であるという問題があったため、このcomponent.parentForm = fb.group({});
を実行してbeforeEachにFormBuilderを注入することで、自分で作成しようとしました。しかし今問題はカルマ/ジャスミンがFormBuilderを見つけることができないということです
_Cannot find name 'FormBuilder'.
_
私がやろうとしているのは、単体テスト中にコンポーネントのインスタンスを作成するときに、parentFormを取得またはモックすることです。これは、foreachの間に新しいコントロールとしてngOnInitを呼び出すためです。
何か案は。ありがとうございました
私は、Reactive Form Parent <-> ChildコンポーネントのKarma仕様テストに成功しました。うまくいけば、以下の例がセットアップのガイドに役立つでしょう。私はコードベースからできるだけ多くのコードを簡略化して、解決しようとしている核となる質問に焦点を当てています。
...
<div [stepControl]="childFormGroup">
<child-form-group [formGroup]="childFormGroup"></child-form-group>
</div>
...
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';
@Component({
selector: 'form-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.scss']
})
export class FormParentComponent implements OnInit {
// childFormGroup will be available on the parent DOM
// so we can inject it / pass it to the ChildFormComponent
public childFormGroup : FormGroup;
constructor(private _formBuilder: FormBuilder) {
this.createForm();
}
private createForm() : void {
this.childFormGroup = this._formBuilder.group({
name: ['Sample Name', Validators.required],
email: ['', Validators.required]
});
}
}
...
<form [formGroup]="formGroup">
<p>This is the childFormGroup</p>
<br>
<div>
<input placeholder="Name"
formControlName="name"
autocomplete="off">
</div>
<div>
<input placeholder="Email"
formControlName="email"
autocomplete="off">
</div>
</form>
...
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { FormGroup } from '@angular/forms';
@Component({
selector: 'child-form-group',
templateUrl: './child.component.html',
styleUrls: ['./child.component.scss'],
})
export class ChildFormComponent {
// This declares an inherited model available to this component
@Input() formGroup : FormGroup;
constructor() { }
/* There is no need to create the formGroup here
hence no constructor method call or ngOnInit() hook...
It will simply inherit the formGroup by passing it as an
attribute on the DOM from parent.component.html
*/
}
import { async, ComponentFixture, TestBed, inject } from '@angular/core/testing';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { FormsModule, ReactiveFormsModule, FormGroup, FormBuilder, Validators } from '@angular/forms';
import { ChildFormComponent } from './child.component';
describe('ChildFormComponent', () => {
let component: ChildFormComponent;
let fixture: ComponentFixture<ChildFormComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
schemas: [
CUSTOM_ELEMENTS_SCHEMA
],
imports: [
FormsModule,
ReactiveFormsModule
],
declarations: [
ChildFormComponent
]
})
.compileComponents();
}));
beforeEach(inject([FormBuilder], (fb: FormBuilder) => {
fixture = TestBed.createComponent(Step2Component);
component = fixture.componentInstance;
/* This is where we can simulate / test our component
and pass in a value for formGroup where it would've otherwise
required it from the parent
*/
component.formGroup = fb.group({
name: ['Other Name', Validators.required],
email: ['', Validators.required]
});
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});