我正在尝试测试NgForm
,并检查更新商店状态时是否设置了表单的值。
@ViewChild('form') form: NgForm;
ngOnInit() {
this.subscription = this.store.select('shoppingList').subscribe(data => {
this.editedItem = data.editedIngredient;
this.form.setValue({
name: this.editedItem.name,
amount: this.editedItem.amount
})
});
}
但是设置值时我得到
There are no form controls registered with this group yet.
If you're using ngModel, you may want to check next tick (e.g. use setTimeout).
还尝试创建假表单并设置它,而不是NgForm
TestBed.createComponent(ShoppingEditComponent).debugElement.componentInstance.form = { value: {}, setValue: (newValue) => { this.value = newValue }};
但是在测试中,它的值永远不会更新,得到空的value
对象。
测试这种情况的最佳方法是什么?
答案 0 :(得分:0)
@ViewChild('form')表单:NgForm;
在ngOnInit生命周期挂钩中将不可用。
首先,您需要在构造函数或ngOnInit中创建一个表单。
只有这样,您才能在现有表单上执行方法。
示例
export class MyComponent {
form: FormGroup;
editedItem;
constructor(
private formBuilder: FormBuilder
) {}
ngOnInit() {
this.createForm();
this.subscribeToShoppingList();
}
private createForm() {
this.form = this.formBuilder.group({
name: null,
amount: null
});
}
private subscribeToShoppingList() {
this.store.select('shoppingList').subscribe(data => {
this.editedItem = data.editedIngredient;
this.form.setValue({
name: this.editedItem.name,
amount: this.editedItem.amount
});
});
}
}
在这种情况下,您无需测试商店返回给您的东西,就足以对以下内容进行单元测试:
const mocks = {
store: {
select: sinon.stub().withArgs('shoppingList').returns(new Subject())
}
};
let component: MyComponent;
describe('MyComponent', () => {
beforeEach(() => {
component = new MyComponent(
new FormBuilder(),
<any> mocks.store
);
});
describe('ngOnInit', () => {
beforeEach(() => {
component.ngOnInit();
});
it('should create form', () => {
expect(component.form).to.be.instanceof(FormGroup);
});
it('should create form with correct fields', () => {
expect(component.form.value).to.haveOwnProperty('name');
expect(component.form.value).to.haveOwnProperty('amount');
});
it('should subscribe to store.shoppingList', () => {
expect(component.store.select).to.be.calledOnce.and.calledWith('shoppingList');
});
it('should set correct data from store to component', () => {
component.store.select.next({
editedIngredient: {
name: 'new',
amount: 100
}
});
expect(component.editedItem.amount.to.eql(100));
expect(component.form.value.name).to.eql('new');
});
});
});
我还没有测试代码,它可能有问题,但是我希望我已经解释了主要思想。