I have a strange behavior on testing Angular RxJS based funtions with Karma/Jasmine.
I have this test:
describe('LoginComponent', () => {
let fixture: ComponentFixture<LoginComponent>;
let component: LoginComponent;
let debugElement: DebugElement;
let location: Location;
let router: Router;
let authServiceSpy: AuthService = {
login: () => null,
user: new BehaviorSubject<UserInterface>(null)
} as jasmine.SpyObj<any>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [
HttpClientTestingModule,
RouterTestingModule,
AppModule,
],
providers: [
{ provide: AuthService, useValue: authServiceSpy },
],
declarations: [
LoginComponent,
]
})
.compileComponents()
.then(() => {
router = TestBed.inject(Router);
location = TestBed.inject(Location);
fixture = TestBed.createComponent(LoginComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement;
});
});
describe('submit form', () => {
it('should navigate to dashboard with correct credentials', fakeAsync(() => {
spyOn(authServiceSpy, 'login').and.returnValue(of(new User()));
const navSpy = spyOn(router, 'navigateByUrl');
const button = debugElement.queryAll(By.css('.login-button'));
fixture.detectChanges();
fixture.whenStable().then(() => {
button[0].nativeElement.click();
tick();
expect(navSpy).toHaveBeenCalledTimes(1);
expect(navSpy).toHaveBeenCalledWith('/dashboard');
});
}));
it('should show error with incorrect credentials', fakeAsync(() => {
spyOn(authServiceSpy, 'login').and.returnValue(throwError('login failed'));
const navSpy = spyOn(router, 'navigateByUrl');
const button = debugElement.queryAll(By.css('.login-button'));
fixture.detectChanges();
fixture.whenStable().then(() => {
button[0].nativeElement.click();
tick();
fixture.detectChanges();
expect(navSpy).toHaveBeenCalledTimes(0);
});
}));
});
});
After run these tests I get this error message:
Error: 1 timer(s) still in the queue.
Then I add flush()
for the start of both it()
funtions. And I get this error:
Expected spy navigateByUrl to have been called 0 times. It was called 1 times.
I tried to use discardPeriodicTasks()
and flushMicrotasks()
too. But not helped.
When I use it()
functions one-by-one with fit()
then all works correctly.
Any idea how can I fix this?
CodePudding user response:
As pointed out by @rmjoia, you need to reset the spy object as it will be reused on related test specs. Resetting can be accomplished through the reset method.
navSpy.calls.reset
I would recommend doing this on the beforeEach
function.
Another solution would be splitting the tests into two test suites