遇到了这个问题并在互联网上搜索了fixture.detectChanges(),当显式插入模拟数据时,它无法识别@Input()中的变化.有大量的线程和文档描述了设置,但不一定是为什么它会导致我的所有测试都破坏.
Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked.
删除fixture.detectChanges()似乎“解决”了这个错误.但是现在没有检测到任何新模拟数据(按规格)的插入.
例:
TestComponent.ts
import { TestComponent } from './test-component'; import { TestComponentModule } from './test-component.module'; import { Data } from './interfaces/data'; export class TestComponent { @Input() data: Data; displayData(){ let firstName = data.first; let lastName = data.last; let fullName = firstName + ' ' + lastName; return fullName; }; }
TestComponent.spec.ts
import { ComponentFixture,TestBed } from '@angular/core/testing'; import { TestComponent } from './test-component'; import { TestComponentModule } from './test-component.module'; class DataMock { data: Data = getDataMock({ first: 'Roger',last: 'Moore' }); }; describe('TestComponent',() => { 'use strict'; let testComponent: TestComponent; let fixture: ComponentFixture<TestComponent>; beforeEach(async() => { TestBed.configureTestingModule({ imports: [ TestComponentModule ] }).compileComponents(); fixture = TestBed.createComponent(TestComponent); testComponent = fixture.componentInstance; fixture.detectChanges(); }); it('should render the app',() => { expect(TestComponent).toBeDefined(); }); describe('displayData()',() => { let dataMock = new DataMock; beforeEach(() => { testComponent.data = dataMock.data; }); it('should return fullName',() => { expect(TestComponent.displayData()).toBe('Roger Moore'); }); }); });
>最初,类dataMock被定义为const变量 – 在这种情况下,fixture.detectChanges()会中断它应用的所有测试.
>现在,dataMock是一个带有模拟Input()数据的类,fixture.detectChanges()似乎再次起作用
那么,为什么在fixture.detectChanges()工作的每个规范之前实例化类dataMock?这是什么原因?
解决方法
您必须在执行compileComponents后创建夹具.
beforeEach(async() => { TestBed.configureTestingModule({ imports: [ TestComponentModule ] }).compileComponents(); }); beforeEach(() => { fixture = TestBed.createComponent(TestComponent); testComponent = fixture.componentInstance; fixture.detectChanges(); });