当使用禁用但未禁用的querySelector属性时,用于验证按钮禁用的Angular 6单元测试用例失败

当使用禁用但未禁用的querySelector属性时,用于验证按钮禁用的Angular 6单元测试用例失败,angular,typescript,unit-testing,jasmine,Angular,Typescript,Unit Testing,Jasmine,我是Angular的新手,尝试使用Jasmine编写2个单元测试用例。一个测试用于按钮启用时,另一个测试用于按钮禁用时。 这是要求……当用户在文本框中输入有效数据时,按钮被启用。如果用户在文本框中输入无效数据,则该按钮将被禁用。初始值已禁用。 这是文本框和按钮html: <input type="text" matInput formControlName = 'triplegOriginControl' [(ngMode

我是Angular的新手,尝试使用Jasmine编写2个单元测试用例。一个测试用于按钮启用时,另一个测试用于按钮禁用时。
这是要求……当用户在文本框中输入有效数据时,按钮被启用。如果用户在文本框中输入无效数据,则该按钮将被禁用。初始值已禁用。 这是文本框和按钮html:

<input
      type="text"
      matInput
      formControlName = 'triplegOriginControl'
      [(ngModel)]="leg.originId"
      [matAutocomplete]="autoTripLegOrigin"
      class = 'trip-origin-input'
      (keydown.Tab)="onKey($event)"
  />

  <mat-autocomplete autoActiveFirstOption #autoTripLegOrigin="matAutocomplete">
    <mat-option
      *ngFor="let option of triplegOriginOptions | async"
      [value]="option"
    >
      {{ option }}
    </mat-option>
  </mat-autocomplete>
  <mat-error *ngIf="triplegForm.controls['triplegOriginControl'].hasError('invalid')">
    Please select a valid location
</mat-error>
</mat-form-field>
....
<mat-toolbar color="primary">
<button
  mat-raised-button
  color="primary"
  id="mat-toolbar__get-rate-button-id"
  [disabled] = !triplegForm.valid
>
  GET RATE
</button>
</mat-toolbar>
这是两个单元测试

describe('Enable or Disable Get Rates Button', () => {
     beforeEach(() => {
       fetchDataService.locationArray = ["STOC/4958", "NSGR/4143", "ZCRC/416", "NSGR/4143"];
     });

    it('should enable the button when Origin and Destination are valid', (done) => {
      const compiled = fixture.debugElement.nativeElement;
      const originIdInput = compiled.querySelector(
        ".trip-origin-input"
      );
      originIdInput.value = "STOC/4958";
      originIdInput.dispatchEvent(new Event("input"));

      const destinationIdInput = compiled.querySelector(
        ".trip-destination-input"
      );
      destinationIdInput.value = "NSGR/4143";
      destinationIdInput.dispatchEvent(new Event("input"));
      fixture.detectChanges();

      fixture.whenStable().then(() => {
        expect(fixture.componentInstance.leg.originId).toBe('STOC/4958');
        expect(fixture.componentInstance.leg.destinationId).toBe('NSGR/4143');
        expect(compiled.querySelector('#mat-toolbar__get-rate-button-id').disable).toBeFalsy();
        done();
      });
    });

    it('should disable the button when Origin and Destination are invalid', (done) => {
      const compiled = fixture.debugElement.nativeElement;
      const originIdInput = compiled.querySelector(
        ".trip-origin-input"
      );
      originIdInput.value = "546";
      originIdInput.dispatchEvent(new Event("input"));

      const destinationIdInput = compiled.querySelector(
        ".trip-destination-input"
      );
      destinationIdInput.value = "NSGxx/43";
      destinationIdInput.dispatchEvent(new Event("input"));
      fixture.detectChanges();

      fixture.whenStable().then(() => {
        expect(fixture.componentInstance.leg.originId).toBe('546');
        expect(fixture.componentInstance.leg.destinationId).toBe('NSGxx/43');
        expect(compiled.querySelector('#mat-toolbar__get-rate-button-id').disable).toBeTruthy();
        done();
      });
    });
  });
使用时:

expect(compiled.querySelector('#mat-toolbar__get-rate-button-id').disable)
第一次测试(有效测试)失败。 错误:预期true为false。 使用属性disabled时,有效测试通过

使用时

expect(compiled.querySelector('#mat-toolbar__get-rate-button-id').disabled)
第二次测试(无效测试)失败。 **错误:预期未定义为真实** 使用属性disable时,无效测试通过

属性禁用禁用之间有什么区别? 代码按预期工作。当用户输入无效值时,按钮被禁用。当输入有效值时,按钮被启用。
如何更正这些测试用例

我认为
.disable
使用JavaScript/HTML禁用输入,我不确定
.disabled
的作用。我将使用属性选择器检查属性

1.
compiled
在更改和更改检测之前仍然引用DOM/HTML,每次更改时都需要一个新的引用

2.)使用[disabled]属性CSS选择器,查看它何时存在或何时不存在

试试这个,我添加了一些评论:

    it('should enable the button when Origin and Destination are valid', (done) => {
      const compiled = fixture.debugElement.nativeElement;
      const originIdInput = compiled.querySelector(
        ".trip-origin-input"
      );
      originIdInput.value = "STOC/4958";
      originIdInput.dispatchEvent(new Event("input"));

      const destinationIdInput = compiled.querySelector(
        ".trip-destination-input"
      );
      destinationIdInput.value = "NSGR/4143";
      destinationIdInput.dispatchEvent(new Event("input"));
      fixture.detectChanges();

      fixture.whenStable().then(() => {
        expect(fixture.componentInstance.leg.originId).toBe('STOC/4958');
        expect(fixture.componentInstance.leg.destinationId).toBe('NSGR/4143');
        // since you did fixture.detectChanges, you need a new reference to the dom
        // compiled is still pointing to the previous instance.
        const newCompiled = fixture.debugElement.nativeElement;
        // attach the attribute selector of [disabled] and expect it to not be there
        console.log(!component.triplegForm.valid); // ensure you see false here
        expect(newCompiled.querySelector('#mat-toolbar__get-rate-button-id[disabled]')).toBeFalsy();
        done();
      });
    });

    it('should disable the button when Origin and Destination are invalid', (done) => {
      const compiled = fixture.debugElement.nativeElement;
      const originIdInput = compiled.querySelector(
        ".trip-origin-input"
      );
      originIdInput.value = "546";
      originIdInput.dispatchEvent(new Event("input"));

      const destinationIdInput = compiled.querySelector(
        ".trip-destination-input"
      );
      destinationIdInput.value = "NSGxx/43";
      destinationIdInput.dispatchEvent(new Event("input"));
      fixture.detectChanges();

      fixture.whenStable().then(() => {
        expect(fixture.componentInstance.leg.originId).toBe('546');
        expect(fixture.componentInstance.leg.destinationId).toBe('NSGxx/43');
        // same logic here
        console.log(!component.triplegForm.valid); // ensure you see true here
        const newCompiled = fixture.debugElement.nativeElement;
        expect(newCompiled.querySelector('#mat-toolbar__get-rate-button-id[disabled]')).toBeTruthy();
        done();
      });
    });

尝试了你的建议,但失败了,出现了另一个错误:错误:预期。。。对falsy进行了仔细研究,发现如果我使用此选择器,有效测试将通过:#mat-toolbar_uuget-rate-button-id已禁用,但如果我使用此选择器,无效测试将失败。如果我使用这个选择器#mat-toolbar uu get-rate-button-id[disabled]无效案例通过它是一个假阳性,它通过了,因为它不在那里。我对CSS选择器很有信心,可能有一种类型,但是CSS选择器需要
[]
(硬括号)。查看console.log of!我添加了component.tripleForm.valid并确保您看到准确的值。如果值准确,可能需要在then回调的
fixture.whenStable()
之后再添加一个
fixture.detectChanges()
。对于这两种情况,component.tripleForm.valid都为false。valid标志使用自定义验证器。此验证器转到服务以获取有效位置。服务已初始化:*在每个(()=>{fetchDataService.locationArray=[“UPPH/4097”、“CACN/4030”、“ZCRC/416”、“NSGR/4143”、“ZCRC/471”、“REPH/4987”];})之前**找到了…位置数组没有我输入的位置。因此,案例正确无效,因为位置不在数组中。非常感谢你的帮助!
    it('should enable the button when Origin and Destination are valid', (done) => {
      const compiled = fixture.debugElement.nativeElement;
      const originIdInput = compiled.querySelector(
        ".trip-origin-input"
      );
      originIdInput.value = "STOC/4958";
      originIdInput.dispatchEvent(new Event("input"));

      const destinationIdInput = compiled.querySelector(
        ".trip-destination-input"
      );
      destinationIdInput.value = "NSGR/4143";
      destinationIdInput.dispatchEvent(new Event("input"));
      fixture.detectChanges();

      fixture.whenStable().then(() => {
        expect(fixture.componentInstance.leg.originId).toBe('STOC/4958');
        expect(fixture.componentInstance.leg.destinationId).toBe('NSGR/4143');
        // since you did fixture.detectChanges, you need a new reference to the dom
        // compiled is still pointing to the previous instance.
        const newCompiled = fixture.debugElement.nativeElement;
        // attach the attribute selector of [disabled] and expect it to not be there
        console.log(!component.triplegForm.valid); // ensure you see false here
        expect(newCompiled.querySelector('#mat-toolbar__get-rate-button-id[disabled]')).toBeFalsy();
        done();
      });
    });

    it('should disable the button when Origin and Destination are invalid', (done) => {
      const compiled = fixture.debugElement.nativeElement;
      const originIdInput = compiled.querySelector(
        ".trip-origin-input"
      );
      originIdInput.value = "546";
      originIdInput.dispatchEvent(new Event("input"));

      const destinationIdInput = compiled.querySelector(
        ".trip-destination-input"
      );
      destinationIdInput.value = "NSGxx/43";
      destinationIdInput.dispatchEvent(new Event("input"));
      fixture.detectChanges();

      fixture.whenStable().then(() => {
        expect(fixture.componentInstance.leg.originId).toBe('546');
        expect(fixture.componentInstance.leg.destinationId).toBe('NSGxx/43');
        // same logic here
        console.log(!component.triplegForm.valid); // ensure you see true here
        const newCompiled = fixture.debugElement.nativeElement;
        expect(newCompiled.querySelector('#mat-toolbar__get-rate-button-id[disabled]')).toBeTruthy();
        done();
      });
    });