【问题标题】:unit test fails when the component is marked as ChangeDetectionStrategy.OnPush当组件被标记为 ChangeDetectionStrategy.OnPush 时单元测试失败
【发布时间】:2021-01-30 05:00:34
【问题描述】:

我有角度分量 l

@Component({
  selector: 'aas-add-option',
  templateUrl: './add-option-modal.component.html',
  styleUrls: ['./add-option-modal.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})

有表单组

this.formBuilder.group({
      newOptionInput: new FormControl('', [
        Validators.required,
        Validators.maxLength(150),
        Validators.pattern(this.htmlPattern),
      ]),
      newOptionHint: new FormControl(''),
    });

=============================== .html 文件

<vt-modal-footer>
    <button
      vtButton
      ot-auto-id="AAResultsAddModalCancelButton"
      [disabled]="isLoading"
      (click)="closeModal()"
    >
      {{ 'Cancel' | translate }}
    </button>
    <button
      vtButton
      color="neutral"
      class="slds-m-right_medium"
      ot-auto-id="AAResultsAddModalSaveAndAddAnotherButton"
      [disabled]="
        !optionsForm?.get('newOptionInput').value?.trim() ||
        !optionsForm?.get('newOptionInput').valid   <--HERE BUTTON DISABLED CHECK
      "
      (click)="onSaveAndAddAnother()"
    >
      {{ 'SaveAndAddAnother' | translate }}
    </button>
    <button
      vtButton
      color="primary"
      *ngIf="!isLoading"
      ot-auto-id="AAResultsAddModalSaveButton"
      [disabled]="
        !optionsForm?.get('newOptionInput').value?.trim() ||   <--HERE BUTTON DISABLED CHECK
        !optionsForm?.get('newOptionInput').valid
      "
      (click)="addOption(true)"
    >
      {{ 'Save' | translate }}
    </button>
  </vt-modal-footer>

spec.ts

fit('should saveNewOptionButton and saveAndAddAnotherButton should get enabled, when the value is set in input', () => { 
    const saveNewOptionButtonElement = fixture.debugElement.query(
      By.css('button[ot-auto-id="AAResultsAddModalSaveButton"]')
    );
    const saveAndAddAnotherButtonElement = fixture.debugElement.query(
      By.css('button[ot-auto-id="AAResultsAddModalSaveAndAddAnotherButton"]')
    );

    //fixture.nativeElement.querySelector('[ot-auto-id="AAResultsNewOptionInput"]').value = 'ravi'; // basically I want to test, by setting like this.
     
    component.optionsForm.controls.newOptionInput.setValue('ravi'); //trying this too
    fixture.detectChanges();
    expect(component.optionsForm.valid).toBeTruthy(); <- got failed 
    expect(saveNewOptionButtonElement.nativeElement.disabled).toBe(false); <- got failed 
    // expect(saveAndAddAnotherButtonElement.nativeElement.disabled).toBe(false); <- got failed 
  });

现在我需要通过将值设置为输入 DOM 来对 Formcontrol 进行单元测试,并期望启用按钮,因为该值是在规范中设置的,

但如果我从@Component 中删除changeDetection: ChangeDetectionStrategy.OnPush,一切正常,但我希望更改检测策略在组件上。

所以问题是为什么我的规范在 @Component 有 changeDetection: ChangeDetectionStrategy.OnPush 以及我应该进行哪些更改以使其在我的规范中起作用

【问题讨论】:

标签: javascript angular jasmine angular-forms


【解决方案1】:

在测试中使用 OnPush 组件时,您应该注意fixture.detectChanges() 不会在 undeflying 组件的视图上触发更改检测,而是在主机视图上触发。

为了纠正这种行为,您可以像这样获取实际组件的 changeDetector:

// fixture.changeDetectorRef.markForCheck();
const cdRef = fixture.componentRef.injector.get(ChangeDetectorRef);
cdRef.detectChanges();

【讨论】:

  • 感谢您的回答,但根据最新的角度,这是固定的。我刚刚升级了 Angular 的最新版本,它开始工作了。谢谢你的回答
猜你喜欢
  • 2010-11-28
  • 1970-01-01
  • 1970-01-01
  • 2011-05-02
  • 1970-01-01
  • 2017-12-02
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
相关资源
最近更新 更多