通过 Jasmine 中的@input 模拟父 FormGroup
Mocking a parent FormGroup via @input in Jasmine
所以我有一个类似这样的子组件
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 来自己构建它。但是现在的问题是 karma/jasmine 找不到 FormBuilder
Cannot find name 'FormBuilder'.
我想做的就是在单元测试期间创建组件实例时尝试获取或模拟 parentForm,我需要它,因为我在 for each 期间调用 ngOnInit,因为它是新控件。
任何想法。谢谢
我能够为 Reactive Form Parent <-> Child 组件设置成功的 Karma 规范测试。希望下面的示例将有助于指导您的设置。我已尽可能多地简化我的代码库中的代码,以专注于您要解决的核心问题。
父组件
parent.component.html
...
<div [stepControl]="childFormGroup">
<child-form-group [formGroup]="childFormGroup"></child-form-group>
</div>
...
parent.component.ts
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]
});
}
}
子组件
child.component.html
...
<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>
...
child.component.ts
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
*/
}
child.component.spec.ts
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();
});
});
所以我有一个类似这样的子组件
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 来自己构建它。但是现在的问题是 karma/jasmine 找不到 FormBuilder
Cannot find name 'FormBuilder'.
我想做的就是在单元测试期间创建组件实例时尝试获取或模拟 parentForm,我需要它,因为我在 for each 期间调用 ngOnInit,因为它是新控件。
任何想法。谢谢
我能够为 Reactive Form Parent <-> Child 组件设置成功的 Karma 规范测试。希望下面的示例将有助于指导您的设置。我已尽可能多地简化我的代码库中的代码,以专注于您要解决的核心问题。
父组件
parent.component.html
...
<div [stepControl]="childFormGroup">
<child-form-group [formGroup]="childFormGroup"></child-form-group>
</div>
...
parent.component.ts
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]
});
}
}
子组件
child.component.html
...
<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>
...
child.component.ts
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
*/
}
child.component.spec.ts
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();
});
});