9

I upgraded the Jest library to v25 and all unit tests that were checking location change are failing.

I checked a couple of issues opened on the Jest repository, but I didn't actually understand how can this be fixed.

The code that calls location.assign breaks with the following error:

Error: Not implemented: navigation (except hash changes)

      69 |     // window.location.href = url;
    > 70 |     window.location.assign(url);

I suppose that the Jest jsdom window object shouldn't be treated any more like a real browser window with regards to changing the location.

How can I fix this?


My findings:

  • Navigation in the tests doesn't work. All these methods that work in the browser are not implemented in the JSDom window:
    • window.location.href = "https://myapp.com"
    • window.location.assign("https://myapp.com")
    • window.location.replace("https://myapp.com")
    • Object.defineProperty(window.location, "href", { writable: true, value: currentUrl }); window.location has been set as Unforgeable

To fix failing tests I used:

  1. window.history.pushState({}, "title", "/testJest");

  2. delete window.location; window.location = { assign: jest.fn() };

    it("should navigate to the new URL", () => { const myUrl = "http://some.url"; expect(window.location.assign).toHaveBeenCalledWith(myUrl); });

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mihai
  • 631
  • 1
  • 14
  • 30

3 Answers3

4

Just add the following code in your test file.

  Object.defineProperty(window, 'location', {
    writable: true,
    value: { assign: jest.fn() }
  });
Sushil Kumar
  • 1,401
  • 2
  • 14
  • 27
  • An explanation would be in order. E.g., what is the idea/gist? From [the Help Center](https://stackoverflow.com/help/promotion): *"...always explain why the solution you're presenting is appropriate and how it works"*. Please respond by [editing (changing) your answer](https://stackoverflow.com/posts/70968655/edit), not here in comments (***without*** "Edit:", "Update:", or similar - the answer should appear as if it was written today). – Peter Mortensen Aug 04 '22 at 20:18
2

To keep it short, "global" is "window" in Jest.

Use:

global.location.assign(url);

I believe that you can find the rest of the answer in How can I mock the JavaScript window object using Jest?.

Also, there is an interesting conversation around this on this issue:

I found window is global in Jest from Stack Overflow, but not mentioned in documentation #3692

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Yalung Tang
  • 613
  • 4
  • 10
1

Following worked for me:

    window.history.replaceState({}, "", decodeURIComponent(url));

happy coding :)

Luckylooke
  • 4,061
  • 4
  • 36
  • 49
  • How is that related to *window.location*? Are you sure it is not accidental? Can you elaborate? – Peter Mortensen Aug 04 '22 at 20:20
  • It changes window.location automatically just try it yourself in console here... I copy pasted this url and added `q` param into it instead of url variable in snippet `window.history.replaceState({}, "", decodeURIComponent('https://stackoverflow.com/questions/59954101/jest-error-when-setting-or-assigning-window-location/72365703?noredirect=1#comment129349849_72365703?q=dasdasdas'));` voila, works without refresh :) – Luckylooke Aug 08 '22 at 17:04
  • For double check you can even call `window.location + ''` in console afterwards to see that it returns changed windo.location url ;) – Luckylooke Aug 08 '22 at 17:06