How can jestjs test a function that uses performance.now()?

8.4k views Asked by At

I'm writing a jestjs test for a ES6 class that uses performance.now(). But it doesn't seem to work.

Is there a way to user perf-hooks globally from the jest.config.js? Or a way to mock performance and override it with eg Date?

I've tried overriding performance on classToTest.js with Date but since it uses performancealready on import that doesn't work.

Simplified examples:

classToTest.test.js

import ClassToTest from "./classToTest";

test("constructor works", () => {
  expect(new ClassToTest()).not.toBeNull();
});

classToTest.js

const timer = performance.now();

class ClassToTest {
...

The output from jest is ReferenceError: performance is not defined.

2

There are 2 answers

2
Brian Adams On BEST ANSWER

If your Jest test environment is jsdom (the default) then it provides a browser-like environment that includes a mock for performance on the global Window object, so performance.now will be defined automatically.

If your Jest test environment is node then you will need to provide your own performance global.

That can be done by adding a setup file to the setupFilesAfterEnv array:

jest.config.js

module.exports = {
  setupFilesAfterEnv: [ './setup.js' ]
}

...and within the setup file defining a global performance:

setup.js

global.performance = require('perf_hooks').performance;
0
nexuzzz On

Update 2024

With the latest jest version performance.now() can be tweaked using fake timers.

Here is an example:

jest.useFakeTimers({
    now: new Date("2024-02-07T00:00:01.123Z"),
});
const start = performance.now();

jest.advanceTimersByTime(1234.5678);
const end = performance.now();

expect(end - start).toBe(1234.5678);