Angular 角度业力Jasmine错误表达式ChangedTerithasBeenCheckedError:表达式在检查后已更改

Angular 角度业力Jasmine错误表达式ChangedTerithasBeenCheckedError:表达式在检查后已更改,angular,karma-jasmine,angular-changedetection,change-detector-ref,Angular,Karma Jasmine,Angular Changedetection,Change Detector Ref,我在AngularV5上,正在编写浅层组件测试。当karma运行测试时,我得到一个错误: Failed: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'false'. Current value: 'true'. Error: ExpressionChangedAfterItHasBeenCheckedError: Expres

我在AngularV5上,正在编写浅层组件测试。当karma运行测试时,我得到一个错误:

Failed: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'false'. Current value: 'true'.

Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'false'. Current value: 'true'.
    at viewDebugError (webpack:///./node_modules/@angular/core/esm5/core.js?:9970:32)
    at expressionChangedAfterItHasBeenCheckedError (webpack:///./node_modules/@angular/core/esm5/core.js?:9948:12)
    at checkBindingNoChanges (webpack:///./node_modules/@angular/core/esm5/core.js?:10117:15)
    at checkNoChangesNodeInline (webpack:///./node_modules/@angular/core/esm5/core.js?:14170:9)
    at checkNoChangesNode (webpack:///./node_modules/@angular/core/esm5/core.js?:14142:9)
    at debugCheckNoChangesNode (webpack:///./node_modules/@angular/core/esm5/core.js?:14971:45)
    at debugCheckRenderNodeFn (webpack:///./node_modules/@angular/core/esm5/core.js?:14911:13)
    at Object.eval [as updateRenderer] (ng:///DynamicTestModule/LocationScheduleComponent.ngfactory.js:207:5)
    at Object.debugUpdateRenderer [as updateRenderer] (webpack:///./node_modules/@angular/core/esm5/core.js?:14893:21)
    at checkNoChangesView (webpack:///./node_modules/@angular/core/esm5/core.js?:13982:14)
当我运行应用程序并手动执行测试场景时,不会发生此错误。我确实进行了一些调试,html中的以下行导致了错误:

<i id="save-new-{{i}}" *ngIf="row.get('IsFast').value" class="save_new_icon"
以下是我的测试代码:

import {FastCarComponent} from "./fast-car.component";
import {async, ComponentFixture, TestBed, fakeAsync, tick, flush, discardPeriodicTasks} from "@angular/core/testing";
import {FormsModule, ReactiveFormsModule} from "@angular/forms";
import {DebugElement, NO_ERRORS_SCHEMA} from "@angular/core";
import {Observable} from "rxjs/Rx";
import {Region} from "../core/models/master/region.model";
import {MockActivatedRoute} from "../../testing/mock-activated-route";
import {By} from "@angular/platform-browser";
import {forEach} from "@angular/router/src/utils/collection";
import {click} from "../../testing";
import {DatePickerAdapter, DatePickerComponent} from "../core/components";
import {CoreModule} from "../core/core.module";

describe('FastCarComponent', () => {
...
    beforeEach(async(() => {
      TestBed.configureTestingModule({
        declarations: [ FastCarComponent, DatePickerComponent ],
        imports: [
          NgSelectModule,
          FormsModule,
          ReactiveFormsModule,
        ],
        providers: [
        ...
        ],
        schemas: [NO_ERRORS_SCHEMA]
      })
        .compileComponents();
    }));


    fit('should clear Car Description Validation Error on Adding Fast Car when DisplayFastCar=true and car description validation is satisfied', async(() => {
      fixture = TestBed.createComponent(FastCarComponent);
      component = fixture.componentInstance;
      component.DisplayFastCar = true;
      fixture.detectChanges();  // ngOnInit()
      const page: Page = new Page(fixture);
      click(page.addBtn);
      fixture.detectChanges();
      fixture.whenStable().then(() => {
        let error_span = page.getErrorSpanByTextContent(CAR_DESCRIPTION_ERROR); //get the validation error that shows on page
        if (error_span) {
          carControl = page.getInputByLabelName('Car Description');
          if (carControl) {
            carControl.value = 'Some Description';
            carControl.dispatchEvent(new Event('input'));
          } else {
            fail(`Could not find control with label Car Description`);
          }

        } else {
          fail(`Did Not Find following validation message: ${CAR_DESCRIPTION_ERROR}`);
        }
      });

      fixture.detectChanges(); //run change detection
      fixture.whenStable().then(() => {
        //fixture.detectChanges();
        let error_span = page.getErrorSpanByTextContent(CAR_DESCRIPTION_ERROR);
        expect(error_span).toBeFalsy(`Found Error Span With Text: ${CAR_DESCRIPTION_ERROR}`);
      });
    }));
  });
});
import {FastCarComponent} from "./fast-car.component";
import {async, ComponentFixture, TestBed, fakeAsync, tick, flush, discardPeriodicTasks} from "@angular/core/testing";
import {FormsModule, ReactiveFormsModule} from "@angular/forms";
import {DebugElement, NO_ERRORS_SCHEMA} from "@angular/core";
import {Observable} from "rxjs/Rx";
import {Region} from "../core/models/master/region.model";
import {MockActivatedRoute} from "../../testing/mock-activated-route";
import {By} from "@angular/platform-browser";
import {forEach} from "@angular/router/src/utils/collection";
import {click} from "../../testing";
import {DatePickerAdapter, DatePickerComponent} from "../core/components";
import {CoreModule} from "../core/core.module";

describe('FastCarComponent', () => {
...
    beforeEach(async(() => {
      TestBed.configureTestingModule({
        declarations: [ FastCarComponent, DatePickerComponent ],
        imports: [
          NgSelectModule,
          FormsModule,
          ReactiveFormsModule,
        ],
        providers: [
        ...
        ],
        schemas: [NO_ERRORS_SCHEMA]
      })
        .compileComponents();
    }));


    fit('should clear Car Description Validation Error on Adding Fast Car when DisplayFastCar=true and car description validation is satisfied', async(() => {
      fixture = TestBed.createComponent(FastCarComponent);
      component = fixture.componentInstance;
      component.DisplayFastCar = true;
      fixture.detectChanges();  // ngOnInit()
      const page: Page = new Page(fixture);
      click(page.addBtn);
      fixture.detectChanges();
      fixture.whenStable().then(() => {
        let error_span = page.getErrorSpanByTextContent(CAR_DESCRIPTION_ERROR); //get the validation error that shows on page
        if (error_span) {
          carControl = page.getInputByLabelName('Car Description');
          if (carControl) {
            carControl.value = 'Some Description';
            carControl.dispatchEvent(new Event('input'));
          } else {
            fail(`Could not find control with label Car Description`);
          }

        } else {
          fail(`Did Not Find following validation message: ${CAR_DESCRIPTION_ERROR}`);
        }
      });

      fixture.detectChanges(); //run change detection
      fixture.whenStable().then(() => {
        //fixture.detectChanges();
        let error_span = page.getErrorSpanByTextContent(CAR_DESCRIPTION_ERROR);
        expect(error_span).toBeFalsy(`Found Error Span With Text: ${CAR_DESCRIPTION_ERROR}`);
      });
    }));
  });
});