问题
I have a close function in my component that contains a setTimeout()
in order to give time for the animation to complete.
public close() {
this.animate = "inactive"
setTimeout(() => {
this.show = false
}, 250)
}
this.show
is bound to an ngIf
.
this.animate
is bound to an animation.
I have a test that needs to test this function
it("tests the exit button click", () => {
comp.close()
fixture.detectChanges()
//verifies the element is no longer in the DOM
const popUpWindow = fixture.debugElement.query(By.css("#popup-window"))
expect(popUpWindow).toEqual(null)
})
How do you properly test this function when there is a setTimeout()
?
I was using jasmine.clock().tick(251)
but the window would never disappear. any thoughts on this as well?
回答1:
You could do one of two things:
1: Actually wait in the test 250+1 ms in a setTimeout()
, then check if the element actually disappeared.
2: use fakeAsync()
and tick()
to simulate time in the test - a tick()
will resolve the setTimeout in the original close()
, and the check could happen right after in a fixture.whenStable().then(...)
.
For example:
it("tests the exit button click", fakeAsync(() => {
comp.close()
tick(500)
fixture.detectChanges()
fixture.whenStable().then(() => {
const popUpWindow = fixture.debugElement.query(By.css("#popup-window"))
expect(popUpWindow).toBe(null)
})
}))
I suggest using the 2nd one, as it is much more faster than actually waiting for the original method. If you still use the 1st, try lowering the timeout time before the test to make the it run faster.
SEVICES
For services you do not need to call detectChanges
after tick
and do not need to wrap the expect statements within whenStable
. you can do your logic right after tick
.
it('should reresh token after interval', fakeAsync(() => {
// given
const service: any = TestBed.get(CognitoService);
const spy = spyOn(service, 'refreshToken').and.callThrough();
....
// when
service.scheduleTokenRefresh();
tick(TOKEN_REFRESH_INTERVAL);
// then
expect(spy).toHaveBeenCalled();
}));
回答2:
In my component the method is:
hideToast() {
setTimeout( () => {
this.showToast = false;
}, 5000);
}
Test for that (explanation in comments):
it('should hide toast', () => {
component.showToast = true; // This value should change after timeout
jasmine.clock().install(); // First install the clock
component.hideToast(); // Call the component method that turns the showToast value as false
jasmine.clock().tick(5000); // waits till 5000 milliseconds
expect(component.showToast).toBeFalsy(); // Then executes this
jasmine.clock().uninstall(); // uninstall clock when done
});
Hope this helps!!
回答3:
Just tried this in my project and works:
jasmine.clock().tick(10);
来源:https://stackoverflow.com/questions/41772989/test-a-function-that-contains-a-settimeout