What is lolex?
The lolex npm package is a library for JavaScript that allows you to control and manipulate the passage of time. It can be particularly useful in testing environments where you want to simulate specific timing conditions without waiting for real time to pass. It allows you to mock the Date object, timers like setTimeout, setInterval, and setImmediate, as well as nextTick (in Node.js). This can help in creating deterministic tests for time-dependent code.
What are lolex's main functionalities?
Mocking Date
This feature allows you to mock the global Date object, so you can simulate any time you need for testing purposes.
const lolex = require('lolex');
const clock = lolex.install();
console.log(new Date()); // This will show the mocked date
clock.uninstall();
Timers
With lolex, you can simulate the behavior of JavaScript timers (setTimeout, setInterval, and setImmediate), allowing you to test timer-dependent code without real time delays.
const lolex = require('lolex');
const clock = lolex.install();
setTimeout(() => console.log('Timer called'), 1000);
clock.tick(1000); // Manually advance the clock
// 'Timer called' is printed to the console
clock.uninstall();
nextTick
This feature is specific to Node.js and allows you to control the process.nextTick queue, enabling the testing of code that uses nextTick to defer actions.
const lolex = require('lolex');
const clock = lolex.install({toFake: ['nextTick']});
process.nextTick(() => console.log('nextTick called'));
clock.runAll(); // Executes all scheduled nextTick callbacks
clock.uninstall();
Other packages similar to lolex
sinon
Sinon is a testing utility that includes spies, mocks, and stubs, but also features a powerful fake timers system similar to lolex. In fact, lolex is a part of Sinon for handling time-related functionalities. Sinon's fake timers can be used independently of its spying and mocking capabilities, making it a versatile choice for testing time-dependent code.
timekeeper
Timekeeper is a simpler alternative focused solely on mocking the Date object and controlling time in tests. It doesn't offer the extensive timer manipulation features of lolex, such as mocking setTimeout or setInterval, but it's lightweight and easy to use for tests that only need to manipulate the system clock.
jest-fake-timers
Jest, a popular testing framework, includes jest-fake-timers, which provides functionality to mock timers within Jest tests. It offers similar features to lolex, allowing you to advance timers manually and control the JavaScript event loop. It's tightly integrated with Jest, making it a convenient option for projects already using Jest for testing.
Lolex
JavaScript implementation of the timer APIs; setTimeout
, clearTimeout
,
setImmediate
, clearImmediate
, setInterval
, clearInterval
, and
requestAnimationFrame
, along with a clock instance that controls the flow of
time. Lolex also provides a Date
implementation that gets its time from the
clock.
Lolex can be used to simulate passing time in automated tests and other
situations where you want the scheduling semantics, but don't want to actually
wait. Lolex is extracted from Sinon.JS.
Installation
Lolex can be installed using npm
:
npm install lolex
If you want to use Lolex in a browser, you have a few options. Releases are
hosted on the sinonjs.org website. You can also
get the node module and build a file for the browser using browserify:
npm install lolex
npm install browserify
browserify node_modules/lolex/lolex.js
Usage
To use lolex, create a new clock, schedule events on it using the timer
functions and pass time using the tick
method.
var lolex = require("lolex");
var clock = lolex.createClock();
clock.setTimeout(function () {
console.log("The poblano is a mild chili pepper originating in the state of Puebla, Mexico.");
}, 15);
clock.tick(15);
Upon executing the last line, an interesting fact about the
Poblano will be printed synchronously to
the screen. If you want to simulate asynchronous behavior, you have to use your
imagination when calling the various functions.
Faking the native timers
When using lolex to test timers, you will most likely want to replace the native
timers such that calling setTimeout
actually schedules a callback with your
clock instance, not the browser's internals.
To hijack timers in another context, use the install
method. You can then call
uninstall
later to restore things as they were again.
var lolex = require("lolex");
var clock = lolex.install(window);
window.setTimeout(fn, 15);
clock.uninstall();
In 90% av the times, you want to install the timers onto the global object.
Calling install
with no arguments achieves this:
var clock = lolex.install();
API Reference
var clock = lolex.createClock([now])
var clock = lolex.install([context[, now[, toFake]]])
var clock = lolex.install([now[, toFake]])
var id = clock.setTimeout(callback, timeout)
clock.clearTimeout(id)
var id = clock.setInterval(callback, timeout)
clock.clearInterval(id)
var id = clock.setImmediate(callback)
clock.clearImmediate(id)
clock.tick(time)
clock.setSystemTime([now])
This simulates a user changing the system clock while your program is running.
It affects the current time but it does not in itself cause e.g. timers to fire; they will fire exactly as they would have done without the call to setSystemTime().
clock.uninstall()
Date
Running tests
Lolex has a comprehensive test suite. If you're thinking of contributing bug
fixes or suggest new features, you need to make sure you have not broken any
tests. You are also expected to add tests for any new behavior.
On node:
npm test
Or, if you prefer slightly less verbose output:
mocha ./test/lolex-test.js
In the browser
License
BSD 3-clause "New" or "Revised" License (see LICENSE file)