I\'ve been tasked with writing tests for a chat app developed with Angular. Below is the snippet of Angular template code I\'m currently writing tests for:
It turns out this is due to using ChangeDetectionStrategy.OnPush
in the component. Using OnPush
only allows you to call .detectChanges()
one time, so subsequent calls will fail to do anything. I'm not familiar enough with Angular to fully understand why.
I was able to produce the required behaviour by overriding the ChangeDetectionStrategy
in my TestBed configuration.
TestBed.configureTestingModule({
imports: [],
declarations: [TestComponent],
providers: []
})
.overrideComponent(TestComponent, {
set: { changeDetection: ChangeDetectionStrategy.Default }
})
.compileComponents();
The answer provided here https://stackoverflow.com/a/50142134/3765819 fixes the problem. However, there is also another way which I think it can prevent further problems on the UI. The problem I had was similar to the one described on the question, meaning that when testing for a specific string on HTML I could not find it. Even though when running the code it worded fine, the UI was not updated accordingly when testing it.
What I had to do was:
To inject ChangeDetectorRef
into the .ts
file:
constructor(private changeDetector: ChangeDetectorRef) {}
and call it when needed:
this.changeDetector.markForCheck();
I know this question is old, but I recently had this same issue where a spinner would constantly spin on the Karma page because change detection only occurred once. The fix for me is whether to call fixture.detectChanges(true) or fixture.autoDetectChanges(true).
beforeEach(() => {
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
component.titleInputEdit = true
// 'detectChanges' will only test for onPush events:
// fixture.detectChanges();
// 'autoDetectChanges' will continually check for changes until the test is complete.
// This is slower, but necessary for certain UI changes
fixture.autoDetectChanges(true);
debugElement = fixture.debugElement;
});
In my case due to async loading I needed to use fixture.whenStable not just fixture.detectChanges e.g.
it('test description', async(async () => {
await fixture.whenStable();
}));