Jasmine test a setTimeout function throws an error
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
Testing code that uses setTimeout in Jasmine requires controlling the clock because real timers are asynchronous and non-deterministic. Jasmine provides jasmine.clock() to mock setTimeout and setInterval, letting you advance time synchronously with clock.tick(). For testing that errors are thrown inside callbacks, you also need to handle the fact that errors inside setTimeout are not directly catchable by the test. This article covers the patterns for testing setTimeout behavior and error handling with Jasmine.
Basic Clock Mocking
jasmine.clock().install() replaces the native setTimeout with a mock. tick(ms) advances the mock clock and triggers any pending callbacks whose delay has elapsed.
Testing a Function That Uses setTimeout
Testing Error Throwing in setTimeout
Errors thrown inside setTimeout callbacks do not propagate to the caller. To test them, capture the error within the callback:
When Jasmine's mock clock executes the callback synchronously via tick(), any thrown error propagates to the tick() call, making it catchable with expect(...).toThrowError().
Refactoring for Testability
A better pattern is to use error callbacks or Promises instead of throwing inside setTimeout:
Using Async/Await Instead of Clock
For modern code using Promises and setTimeout, test with async/await:
Common Pitfalls
- Forgetting to uninstall the clock: Not calling
jasmine.clock().uninstall()inafterEachleaks the mock clock into subsequent tests, causing unpredictable failures. Always pairinstall()withuninstall(). - Expecting errors to propagate from real
setTimeout: Without Jasmine's mock clock, errors insidesetTimeoutcallbacks go to the global error handler, not to the test. Usejasmine.clock().install()so thattick()executes callbacks synchronously and errors propagate to the caller. - Not ticking enough time: If the code schedules
setTimeout(fn, 1000)and you only tick 999ms, the callback does not execute. Tick at least the full delay amount. - Testing implementation details instead of behavior: Verifying that
setTimeoutwas called with specific arguments couples tests to implementation. Instead, test the observable effect (e.g., the callback was invoked, the state changed) after advancing the clock. - Mixing real and mock timers: Installing Jasmine's clock mocks all timer functions globally. If library code or other tests expect real timers, conflicts arise. Ensure the clock is only installed for tests that need it and uninstalled immediately after.
Summary
- Use
jasmine.clock().install()andtick(ms)to controlsetTimeoutin tests - Always uninstall the clock in
afterEachto prevent test pollution - Errors thrown inside
setTimeoutcallbacks propagate throughtick()when using mock clocks - Use
expect(() => clock.tick(...)).toThrowError()to test errors in timer callbacks - Prefer error callbacks or Promises over throwing inside
setTimeoutfor better testability - For modern async code, combine mock clocks with
async/awaitand microtask flushing
Related reading
- Java Spring Boot How to map my app root “/” to index.html?
- Java Spring Boot How to map my app root “/” to index.html?
- Javadoc package.html or package-info.java
- JavaScript - get the first day of the week from current date
- Java Spring Boot Test How to exclude java configuration class from test context
- Java verify void method calls n times with Mockito
- JavaScript - sync wait for async operation sleep
- Javascript algorithm to find elements in array that are not in another array
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.