Application code is calling location.href = "some-url"
. I want to write a test that verify the navigation redirect has happened.
Using jest on jsdom, I tried to do it with overriding location.href setter using jest mock function and it is working.
But now I can't seems to restore the location.href property at the test cleanup, and it failing the rest of the tests which relay on 'location.href'.
it('test navigation happened', () => { const originalLocationHref = Object.getOwnPropertyDescriptor(window.location, 'href'); // returns undefined spyFn = jest.fn(); Object.defineProperty(window.location, 'href', { set: spyFn, enumerable: true, configurable: true }); someAppCodeThatShouldRedirectToSomeUrl(); expect(spyFn).toBeCalledWith('http://some-url'); // this is working // Cleanup code, not working, because originalLocationHref is undefined Object.defineProperty(window.location, 'href', originalLocationHref); });
What am I missing? Why Object.getOwnPropertyDescriptor(window.location, 'href');
is undefined
?
Is there a better way to intercept navigation events in order to test it?
Thanks
Use location.assign() method instead instead of assigning new location string to location.href. Then you can mock and test it with no problems:
it('test navigation happened', () => { window.location.assign = jest.fn(); // here you call location.assign('http://some-url'); redirectToSomeUrl(); expect(window.location.assign).toBeCalledWith('http://some-url'); // location.href hasn't changed because location.assign was mocked });
Newer jest/jsdom versions do not allow to set window.location.assign
anymore. It can be fixed like this:
delete window.location; window.location = { assign: jest.fn() };
Note that this removes all other objects from window.location, you might need to mock more of its objects depending on your test and application code.
Source: https://remarkablemark.org/blog/2018/11/17/mock-window-location/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With