I am trying to unit test a Login Form, but I am not able to execute it as expected.
TestBed configuration:
beforeEach(() => {
TestBed.configureTestingModule({
imports: [FormsModule],
declarations: [AuthComponent],
});
fixture = TestBed.createComponent(AuthComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('form should be invalid', () => {
component.authForm.controls['email'].markAsTouched();
expect(component.authForm.invalid).toBeTruthy();
});
When the above test executes I am getting the following error
TypeError: Cannot read properties of undefined (reading 'markAsTouched')
.
When modifying the test with fakeAsync
and whenstable
like this
it('form should be invalid', fakeAsync(() => {
fixture.whenStable().then(() => {
component.authForm.controls['email'].markAsTouched();
expect(component.authForm.invalid).toBeTruthy();
});
}));
The test result shows as SPEC HAS NO EXPECTATIONS form should be invalid
.
Not sure what I am doing wrong.
Your updated spec function is mixing real asynchronous code (fixture.whenStable()) with the fake async test zone by using fakeAsync(). You have to pick one. The reason why you are getting that new error is because the function execution is over before the whenStable() promise resolves.
Once you fix your inconsistency, they should work about the same way, waiting for all pending tasks in the macro-task queue like setTimeout() to resolve.
it('form should be invalid', async (() => {
await fixture.whenStable(); // wait until all pending macro tasks are resolves
component.authForm.controls['email'].markAsTouched();
expect(component.authForm.invalid).toBeTruthy();
}));
it('form should be invalid', fakeAsync(() => {
flush(); // invoke all remaining pending macro tasks.
component.authForm.controls['email'].markAsTouched();
expect(component.authForm.invalid).toBeTruthy();
}));
For the life of me I don't know which is better. Also I don't know if this will fix your original problem, since you didn't provide the component code.