【问题标题】:unit test for template reference variable in angular角度模板引用变量的单元测试
【发布时间】:2022-02-18 02:16:09
【问题描述】:

我在 html 中有这段代码,用于禁用 ngAfterViewInit() 上的下拉菜单:

<select-field
        #dueBy
        width="100%"
        label=" "
        formControlName="dueByIndex"
        [options]="dueByValues"
        [ngClass]="{ disableUnEditableFields: showChanges }"
      ></select-field>

select-field 是客户提供的自定义标签。 在组件类中:

@ViewChild('dueBy') dueBySelect;
ngAfterViewInit(): void {
    if (this.showChanges) {
      this.dueBySelect.control.disable();
}

我正在尝试为此编写单元测试,但由于未定义,dueBySelect 即将到来。我环顾四周,但在大多数情况下,模板引用变量是某些方法调用的目标。一种尝试如下:

it('should disable the advanced fields', () => {
    component.showChanges = true; // to go inside the if condition in ts file
    const dueBySelectInput: HTMLInputElement = fixture.debugElement.nativeElement.querySelector('#dueBy');
    console.log(component.dueBySelect); // coming as undefined

请给点建议!!谢谢。

【问题讨论】:

    标签: angular jestjs karma-jasmine


    【解决方案1】:

    当您在测试期间修改组件中的某些内容时(就像您将 showChanges 设置为 true 时所做的那样),您需要在夹具上触发更改检测:

    it('should disable the advanced fields', () => {
        component.showChanges = true;
        fixture.detectChanges();
        const dueBySelectInput: HTMLInputElement = fixture.debugElement.nativeElement.querySelector('#dueBy');
        console.log(component.dueBySelect);
    

    【讨论】:

    • 我这样做了,但是 fixture.detectChanges() 对我抛出了一个错误。 console.error 未处理的承诺拒绝:没有名称的表单控件的值访问器:但即使没有执行 fixture.detectChanges(),在调试时,我看到控件正在通过 component.showChanges 并且 this.dueBySelect 仍然未定义。
    • 你需要运行fixture.detectChanges,否则模板不会更新。它引发错误的事实意味着您没有此测试所需的所有依赖项。 的组件是否在您的 TestingModule 中?
    • 谢谢威尔。我为 添加了组件,旧的错误消失了。目前,我收到一个错误:未处理的承诺拒绝:未处理的承诺拒绝:没有未指定名称属性的表单控件的值访问器;区域: ;任务:Promise.then;值:错误:没有用于具有未指定名称属性的表单控件的值访问器。我环顾四周,运气不佳,如果您有任何建议,请告诉我。谢谢..
    • 您需要将组件提供给 NG_VALUE_ACCESSOR : { 提供: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => SelectFieldComponentThingHere), multi: true }
    • 我已经像这样添加了上面的内容:TestBed.configureTestingModule({//imports, etc}).overrideComponent(Component, { set : { providers: [{provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(( ) => SelectFieldComponentThingHere), multi: true } 是这样的吗?
    【解决方案2】:

    正如 Will 所建议的,我更改了禁用组件的实现。以下是组件的代码:

    this.taskForm.addControl('dueByIndex', this.dueByIndexControl);
    this.dueByIndexControl.disable();
    

    所以,我不再需要@ViewChild。但是如果有人在某些情况下遇到它,我们可以尝试以下方法:

    component.dueBySelect = createMock(FormControl);
    component.dueBySelect.disable = jest.fn(()=>true);
    

    【讨论】:

      猜你喜欢
      • 2021-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-25
      • 2021-06-22
      • 1970-01-01
      • 2016-08-05
      • 1970-01-01
      相关资源
      最近更新 更多