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

2

7

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.

Collimore answered 5/9, 2019 at 19:22 Comment(3)
did you import performance in your classToTest.js? const { performance } = require('perf_hooks')Cienfuegos
Yes that works. Also changing to Date.now() works. But I'd like to be able to test the source code as it is and runs in it's environment, not adapt it to the test environment.Collimore
I'm sorry, I still don't get it. Let's forget about your test for a moment. Assuming ClassToTest code works and is a black box for us, how can it use performance without importing it in the first place?Cienfuegos
R
11

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;
Rapper answered 6/9, 2019 at 16:32 Comment(2)
Thank you, exactly what I was looking for! I had to upgrade my jest installation to make it work though, seems like the setupFilesAfterEnv is a pretty new addition.Collimore
Great answer and explanation. Instead of adding it globally it can also be imported in files where needed like const { performance } = require('perf_hooks') (no installation required as it's part of node).Justis
M
0

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);
Misfit answered 7/2 at 22:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.