16

I have a function, that runs on both node and in the browser, which I want to test with jest:

const myFn = () => {
  if(typeof window !== 'object'){
     return 1;
  }
  return 2;
}

How am I able to set the global window object to undefined, to test the node branch, and that 1 is returned.

e.g.

  test('myTest', ()=> {
      global.window = undefined;
      expect(myFn()).toEqual(1); // result: 2
  });

Ive tried the suggestions here with no success: Mocking globals in Jest

skyboyer
  • 22,209
  • 7
  • 57
  • 64
Daniel Billingham
  • 1,391
  • 5
  • 15
  • 25
  • Does this answer your question? [How can I mock the JavaScript 'window' object using Jest?](https://stackoverflow.com/questions/41885841/how-can-i-mock-the-javascript-window-object-using-jest) – Michael Freidgeim Feb 20 '23 at 04:22

2 Answers2

15

You can try using the @jest-environment docblock, available since v20.0.0, to change the environment for different tests. By default it uses jsdom, but you can change it to use node. Here is an excerpt from their documentation:

/**
 * @jest-environment jsdom
 */

test('use jsdom in this test file', () => {
  const element = document.createElement('div');
  expect(element).not.toBeNull();
});

Ref: https://facebook.github.io/jest/docs/en/configuration.html#testenvironment-string

nbkhope
  • 7,360
  • 4
  • 40
  • 58
  • 6
    Excellent thanks @nbkhope. One extra thing to note, (for my example), is that this comment block has to be declared at the very top of the file before any imports. This obviously means that the set env applies to all tests within that file. You are unable to apply the env for individual tests, say within a describe block. – Daniel Billingham Feb 09 '18 at 08:29
  • Thanks @DanielBillingham I initially missed that in the docs. Having tests in two separate files is not ideal but I can't complain about it too much because it was really easy to set up. – Tetraodon Aug 24 '18 at 06:59
  • @ nbkhope i tried the above but didnt worked with act of react testing library, is there any way to accomplish this . https://stackoverflow.com/questions/59173156/making-the-window-to-different-data-type-in-react-testing-library – Learner Dec 05 '19 at 06:01
3

With new version of jsdom you can do the following:

import { JSDOM } from 'jsdom';

let windowSpy: any;
beforeEach(() => {
  windowSpy = jest.spyOn(global as any, 'window', 'get');
});
afterEach(() => {
  windowSpy.mockRestore();
});

describe('', () => {
  it ('', () => {
    const { window } = new JSDOM();
    windowSpy.mockImplementation(() => window);
    // now you have `window` in test environment
  });
});