Issue
Using Angular/Jasmine/Karma I am testing a function that runs in ngOnInit that will log out a user from 15 minutes inactivity.
Here is the original code:
#setSessionTimeout() {
const clicks$ = fromEvent(document, 'click');
const checkInterval = 60000; // 1 minute
const timeLimit = 15; // 15 minutes
clicks$.pipe(
startWith('fake click'),
switchMap(() =>
interval(checkInterval).pipe(
tap(value => {
console.log(value);
if (value > timeLimit) {
this.router.navigate(['logout']);
}
})
)
)
).subscribe()
}
Here is my test:
fit('should log out a user after 15 minutes of inactivity', fakeAsync(() => {
tick(1000 * 60 * 60 * 60);
fixture.detectChanges();
expect(routerMock.navigate).toHaveBeenCalledWith(['logout']);
}));
I can not get the test to pass. It also looks like that function is not running in the test because I see no console.log out. How can I test this function properly?
Solution
Answered:
Ok, I figure it out. I had a fixture.detectChanges();
in the beforeEach() hook which was placed there by angular's cli when it created the test. If I move that fixture.detectChanges();
out of the beforeEach() and place it in the tests instead, then I can successfully test my logic successfully.
It does not make sense because there is still fixture.detectChanges();
that is called initially per a test, just in the test itself instead of the beforeEach(). Nevertheless, it was the issue and solution.
It should be noted that #setSessionTimeout()
is called in ngOnInit() which complicates the testing situation. If it was a public function that I could test without ngOnInit() kicking it off, it would of not required this workaround.
Here are my tests which I successfully verified no false positives or vice versa:
it('should log out a user after 15 minutes of inactivity', fakeAsync(() => {
fixture.detectChanges();
tick(1000 * 60 * 15); // reaches 14 times
fixture.detectChanges();
tick(1000 * 60 * 15); // reaches 29 times and logs out
fixture.detectChanges();
expect(routerMock.navigate).toHaveBeenCalledWith(['logout']);
discardPeriodicTasks();
}));
it('should not log out a user after 15 minutes of inactivity because user did a click', fakeAsync(() => {
fixture.detectChanges();
tick(1000 * 60 * 15); // reaches 14 times
fixture.detectChanges();
document.dispatchEvent(new MouseEvent('click'));
tick(1000 * 60 * 15); // reaches 29 and does not logout because of click
fixture.detectChanges();
expect(routerMock.navigate).not.toHaveBeenCalledWith(['logout']);
discardPeriodicTasks();
}));
Answered By - dman
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.