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 对象的一到三个键确实是你所期望的。

此外,使用 letconst 而不是 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);