Been running into this one issue and scouring the internet about fixture.detectChanges() where it does not recognize changes in @Input() when explicitly inserting mock data. There are tons of threads and docs that describe the setup but not necessarily why it would cause all of my tests to break.
Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked.
Removing fixture.detectChanges() seems to "resolve" this error. But now insertion of any new mock data (per spec) are not detected.
Example:
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');
});
});
});
So, why is instantiating class dataMock before each spec necessary for the fixture.detectChanges() to work? Is this the reason?
You must create the fixture after compileComponents is executed.
beforeEach(async() => {
TestBed.configureTestingModule({
imports: [ TestComponentModule ]
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(TestComponent);
testComponent = fixture.componentInstance;
fixture.detectChanges();
});