angular 单元测试 FormGroup 上的函数等于函数错误
Function to equal Function error on angular unit test FormGroup
我是 Angular 单元测试的新手,目前我正在为其中一项测试而发疯。
我有一项服务具有一个功能,它接受一些问题并且正在 returning 一个 FormGroup:
import { Injectable } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { QuestionBase } from './question-base';
@Injectable()
export class QuestionControlService {
constructor() { }
toFormGroup(questions: QuestionBase<any>[] ) {
let group: any = {};
questions.forEach(question => {
group[question.key] = question.required ? new FormControl(question.value || '', Validators.required)
: new FormControl(question.value || '');
});
return new FormGroup(group);
}
}
相当直接。然后在我的测试中,我从一些模拟问题中模拟了一个 FormGroup,并期望我的服务功能与 return 相同。当我打印输出时看起来很好,但是期望函数是 returning follow error:
Chrome Headless 91.0.4469.0 (Mac OS 10.15.7) QuestionControlService creates toFormGroup successfully FAILED
Expected $._onCollectionChange = Function to equal Function.
Expected $.controls.name._onCollectionChange = Function to equal Function.
Expected $.controls.username._onCollectionChange = Function to equal Function.
Expected $.controls.email._onCollectionChange = Function to equal Function.
Error: Expected $._onCollectionChange = Function to equal Function.
Expected $.controls.name._onCollectionChange = Function to equal Function.
Expected $.controls.username._onCollectionChange = Function to equal Function.
Expected $.controls.email._onCollectionChange = Function to equal Function.
at <Jasmine>
at UserContext.<anonymous> (src/app/dynamic-form/question-control.service.spec.ts:34:17)
at ZoneDelegate.invoke (node_modules/zone.js/fesm2015/zone.js:372:1)
at ProxyZoneSpec.onInvoke (node_modules/zone.js/fesm2015/zone-testing.js:287:1)
我的测试规范如下所示:
import { TestBed } from '@angular/core/testing';
import { FormGroup, FormControl, Validators } from '@angular/forms';
import { QuestionControlService } from './question-control.service';
describe('QuestionControlService', () => {
let service: QuestionControlService;
beforeEach(() => {
TestBed.configureTestingModule({ providers: [QuestionControlService] });
service = TestBed.inject(QuestionControlService);
});
it('can load instance', () => {
expect(service).toBeTruthy();
});
it('creates toFormGroup successfully', () => {
var mockedQuestions = [
{value: undefined, key: 'name', label: 'Name', required: true, order: 1, group: 1, controlType: 'textbox', type: 'text'},
{value: undefined, key: 'username', label: 'Username', required: false, order: 1, group: 2, controlType: 'textbox', type: 'text'},
{value: 'john@doe.com', key: 'email', label: 'Email', required: true, order: 2, group: 1, controlType: 'textbox', type: 'email'}
]
var mockedGroup = {
'name': new FormControl('', Validators.required),
'username': new FormControl(''),
'email': new FormControl('john@doe.com', Validators.required)
}
var mockedFormGroup = new FormGroup(mockedGroup);
const res = service.toFormGroup(mockedQuestions);
expect(res).toEqual(mockedFormGroup);
});
});
我做错了什么?
另外,我已经测试过创建另一个 return 仅文本的 helloWorld 函数,并且运行良好。所以我的猜测是问题是某种程度上的 return 类型的 FormGroup。
你说得对,我认为这是对象 (FormGroup) 的 return 类型不同于字符串等原始类型。
你最好的选择是获取 res
对象并断言它是正确的。
像这样:
expect(res.controls.get('name')).toBeTruthy();
也许它不是 res.controls,它可以是别的东西,但我们的想法是断言 returned 对象的一到三个键确实是你所期望的。
此外,使用 let
或 const
而不是 var
。
感谢 @alif50 我更改了测试策略。我结束了这个测试:
it('creates toFormGroup successfully', () => {
let mockedQuestions = [
{value: undefined, key: 'name', label: 'Name', required: true, order: 1, group: 1, controlType: 'textbox', type: 'text'},
{value: undefined, key: 'username', label: 'Username', required: false, order: 1, group: 2, controlType: 'textbox', type: 'text'},
{value: 'john@doe.com', key: 'email', label: 'Email', required: true, order: 2, group: 1, controlType: 'textbox', type: 'email'}
]
const res: FormGroup = service.toFormGroup(mockedQuestions);
expect(res.get('name')).toBeTruthy();
expect(res.get('name').errors.required).toEqual(true);
expect(res.get('username')).toBeTruthy();
expect(res.get('username').status).toEqual('VALID');
expect(res.get('email')).toBeTruthy();
expect(res.get('email').value).toEqual('john@doe.com');
expect(res.status).toEqual('INVALID');
});
如果要检查FormGroup中的数据是否相同,只需比较它们的值即可。这不会检查验证器等是否相同,但您可以进行其他测试/期望验证。
expect(res.value).toEqual(mockedFormGroup.value);
我是 Angular 单元测试的新手,目前我正在为其中一项测试而发疯。
我有一项服务具有一个功能,它接受一些问题并且正在 returning 一个 FormGroup:
import { Injectable } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { QuestionBase } from './question-base';
@Injectable()
export class QuestionControlService {
constructor() { }
toFormGroup(questions: QuestionBase<any>[] ) {
let group: any = {};
questions.forEach(question => {
group[question.key] = question.required ? new FormControl(question.value || '', Validators.required)
: new FormControl(question.value || '');
});
return new FormGroup(group);
}
}
相当直接。然后在我的测试中,我从一些模拟问题中模拟了一个 FormGroup,并期望我的服务功能与 return 相同。当我打印输出时看起来很好,但是期望函数是 returning follow error:
Chrome Headless 91.0.4469.0 (Mac OS 10.15.7) QuestionControlService creates toFormGroup successfully FAILED
Expected $._onCollectionChange = Function to equal Function.
Expected $.controls.name._onCollectionChange = Function to equal Function.
Expected $.controls.username._onCollectionChange = Function to equal Function.
Expected $.controls.email._onCollectionChange = Function to equal Function.
Error: Expected $._onCollectionChange = Function to equal Function.
Expected $.controls.name._onCollectionChange = Function to equal Function.
Expected $.controls.username._onCollectionChange = Function to equal Function.
Expected $.controls.email._onCollectionChange = Function to equal Function.
at <Jasmine>
at UserContext.<anonymous> (src/app/dynamic-form/question-control.service.spec.ts:34:17)
at ZoneDelegate.invoke (node_modules/zone.js/fesm2015/zone.js:372:1)
at ProxyZoneSpec.onInvoke (node_modules/zone.js/fesm2015/zone-testing.js:287:1)
我的测试规范如下所示:
import { TestBed } from '@angular/core/testing';
import { FormGroup, FormControl, Validators } from '@angular/forms';
import { QuestionControlService } from './question-control.service';
describe('QuestionControlService', () => {
let service: QuestionControlService;
beforeEach(() => {
TestBed.configureTestingModule({ providers: [QuestionControlService] });
service = TestBed.inject(QuestionControlService);
});
it('can load instance', () => {
expect(service).toBeTruthy();
});
it('creates toFormGroup successfully', () => {
var mockedQuestions = [
{value: undefined, key: 'name', label: 'Name', required: true, order: 1, group: 1, controlType: 'textbox', type: 'text'},
{value: undefined, key: 'username', label: 'Username', required: false, order: 1, group: 2, controlType: 'textbox', type: 'text'},
{value: 'john@doe.com', key: 'email', label: 'Email', required: true, order: 2, group: 1, controlType: 'textbox', type: 'email'}
]
var mockedGroup = {
'name': new FormControl('', Validators.required),
'username': new FormControl(''),
'email': new FormControl('john@doe.com', Validators.required)
}
var mockedFormGroup = new FormGroup(mockedGroup);
const res = service.toFormGroup(mockedQuestions);
expect(res).toEqual(mockedFormGroup);
});
});
我做错了什么?
另外,我已经测试过创建另一个 return 仅文本的 helloWorld 函数,并且运行良好。所以我的猜测是问题是某种程度上的 return 类型的 FormGroup。
你说得对,我认为这是对象 (FormGroup) 的 return 类型不同于字符串等原始类型。
你最好的选择是获取 res
对象并断言它是正确的。
像这样:
expect(res.controls.get('name')).toBeTruthy();
也许它不是 res.controls,它可以是别的东西,但我们的想法是断言 returned 对象的一到三个键确实是你所期望的。
此外,使用 let
或 const
而不是 var
。
感谢 @alif50 我更改了测试策略。我结束了这个测试:
it('creates toFormGroup successfully', () => {
let mockedQuestions = [
{value: undefined, key: 'name', label: 'Name', required: true, order: 1, group: 1, controlType: 'textbox', type: 'text'},
{value: undefined, key: 'username', label: 'Username', required: false, order: 1, group: 2, controlType: 'textbox', type: 'text'},
{value: 'john@doe.com', key: 'email', label: 'Email', required: true, order: 2, group: 1, controlType: 'textbox', type: 'email'}
]
const res: FormGroup = service.toFormGroup(mockedQuestions);
expect(res.get('name')).toBeTruthy();
expect(res.get('name').errors.required).toEqual(true);
expect(res.get('username')).toBeTruthy();
expect(res.get('username').status).toEqual('VALID');
expect(res.get('email')).toBeTruthy();
expect(res.get('email').value).toEqual('john@doe.com');
expect(res.status).toEqual('INVALID');
});
如果要检查FormGroup中的数据是否相同,只需比较它们的值即可。这不会检查验证器等是否相同,但您可以进行其他测试/期望验证。
expect(res.value).toEqual(mockedFormGroup.value);