How to mock window.location.href with Jest in React?
10,295
Solution 1
I ended up with the following on React 16 and Jest 24.
describe("usePageTracking", () => {
let location;
const mockLocation = new URL("https://example.com");
beforeEach(() => {
location = window.location;
mockLocation.replace = jest.fn();
// You might need to mock other functions as well
// location.assign = jest.fn();
// location.reload = jest.fn();
delete window.location;
window.location = mockLocation;
});
afterEach(() => {
window.location = location;
});
// ...
});
See also:
Solution 2
Use Object.defineProperty()
to define a getter for window.location
.
E.g.
usePageTracking.ts
:
import { useEffect } from 'react';
export const usePageTracking = (): void => {
useEffect(() => {
console.log(window.location.href);
}, []);
};
Example.tsx
:
import React from 'react';
import { usePageTracking } from './usePageTracking';
export function Example() {
usePageTracking();
return <div>example</div>;
}
Example.test.tsx
:
import React from 'react';
import { Example } from './Example';
import { render } from '@testing-library/react';
describe('Example', () => {
it('should pass', () => {
Object.defineProperty(window, 'location', {
get() {
return { href: 'stackoverflow.com' };
},
});
render(<Example />);
});
});
test result
PASS examples/63409476/Example.test.tsx (11.048 s)
Example
✓ should pass (39 ms)
console.log
stackoverflow.com
at examples/63409476/usePageTracking.ts:5:13
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 12.768 s
package versions:
"jest": "^26.6.3",
"ts-jest": "^26.4.4",
jest.config.js
:
module.exports = {
preset: 'ts-jest/presets/js-with-ts',
}
Author by
thisismydesign
Updated on June 08, 2022Comments
-
thisismydesign about 2 years
I'm testing functionality that is not supposed to run locally and need to mock
window.location.href
:const usePageTracking = (): void => { const location = useLocation(); useEffect(() => { if (!window.location.href.includes("localhost")) { ReactGA.initialize("UA-000000-01"); ReactGA.pageview(window.location.pathname + window.location.search); } }, []); };
In my tests:
describe("usePageTracking", () => { it("initializes ReactGA", () => { render(<Example />); expect(ReactGA.initialize).toHaveBeenCalled(); }); it("tracks page view", () => { render(<Example />); expect(ReactGA.pageview).toHaveBeenCalledWith("/"); }); });
Note: there's a related question around Vue but it wasn't clear to me if the solutions apply to React as well (some just didn't work).
-
scottwernervt almost 3 yearsObject.defineProperty() worked perfectly with typescript!