javascript - 当组件被标记为 ChangeDetectionStrategy.OnPush 时,单元测试失败

标签 javascript angular jasmine angular-forms

我有 Angular 分量 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>

规范
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 进行单元测试,并期望按钮被启用,因为该值是在规范中设置的,
但是如果我删除 changeDetection: ChangeDetectionStrategy.OnPush从@Component 开始,一切正常,但我希望更改检测策略位于组件上。
所以问题是为什么我的规范在 @Component 有时失败changeDetection: ChangeDetectionStrategy.OnPush以及我应该进行哪些更改以使其在我的规范中工作

最佳答案

在测试中使用 OnPush 组件时,您应该注意 fixture.detectChanges()不会在 undeflying 组件的 View 上触发更改检测,而是在主机 View 上触发。
为了纠正这种行为,您可以像这样获取实际组件的 changeDetector:

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

关于javascript - 当组件被标记为 ChangeDetectionStrategy.OnPush 时,单元测试失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64376162/

相关文章:

javascript - 是否可以发送 Jasmine 2 规范被 xit 或 pending() 跳过的原因?

javascript - 无法对原型(prototype)方法进行单元测试

angular - 在 Angular 中发出值,记录为 [object Object] 而不是值

javascript - 尝试获取 iFrame 窗口时出错

div 标签的 JavaScript 正则表达式

javascript - 访问 iframe 功能

angular - 在 angular2 中使用 ng-model 和 ng-control 的区别?

javascript - 引用错误: browser is not defined - Using Karma and Jasmine

javascript - 在 WebView 中提交表单 - Swift 3.1

javascript - Kotlin JS JSON 反序列化