I've got a piece of code the puts together a full URL for a redirection (something like this):
import { redirect } from './some-utils'
export const goToURL = () => {
const url = window.location.origin + window.location.pathname
redirect(url)
}
Now, I'm trying to write a TypeScript test that tests the URL string:
describe('my-test-file', () => {
let originalWindowLocation
const redirect = jest.fn()
beforeEach(() => {
jest.resetAllMocks()
originalWindowLocation = window.location
})
afterEach(() => {
window.location = originalWindowLocation
})
it('test that redirection URL is correct', () => {
delete window.location // can't do this because TS complains
window.location = { origin: 'https://www.example.com', pathname: '/mypath' } // can't do this because TS complains
goToURL()
expect(redirect).toHaveBeenCalledTimes(1)
expect(redirect).toHaveBeeenCalledWith('https://www.example.com/mypath')
})
})
However, I get two TypeScript errors. On the delete line:
The operand of a 'delete' operator must be optional.
and on the new assignment of window.location:
Type '{ origin: string; pathname: string; }' is not assignable to type 'Location | (string & Location)'. Type '{ origin: string; pathname: string; }' is not assignable to type 'string & Location'. Type '{ origin: string; pathname: string; }' is not assignable to type 'string'.
I tried fixing the first error by removing the delete statement and tried fixing the second error by adding as Location to the end of the assignment. Doing so fixes the TS errors but my test no longer passes. It uses the domain of my web app instead of the example one in my test.
Can anyone help me fix up my TS errors while ensuring that my tests pass?
Edit:
If I try window.location = 'https://www.example.com/mypath', my test still does not pass and I still get a TS error:
Type 'string' is not assignable to type 'Location | (string & Location)'
If I try window.location.href = 'https://www.example.com/mypath', the TS errors go away but the test does not pass.
If I try window.location.assign(https://www.example.com/mypath'), the TS errors go away but the test does not pass.
If you are only using a subset of the Location API that's also available on an instance of URL (e.g. window.location.href = "https://domain.tld/pathname"), then you can manually mock (replace) that property on window during your tests:
describe('description', () => {
let originalWindowLocation = window.location;
beforeEach(() => {
Object.defineProperty(window, 'location', {
configurable: true,
enumerable: true,
value: new URL(window.location.href),
});
});
afterEach(() => {
Object.defineProperty(window, 'location', {
configurable: true,
enumerable: true,
value: originalWindowLocation,
});
});
it('test that redirection URL is correct', () => {
const expectedUrl = 'https://www.example.com/mypath';
window.location.href = expectedUrl;
expect(window.location.href).toBe(expectedUrl);
});
});
I intentionally did not address the other aspects of your code because it's not what you asked about, but if you want to mock a function invocation (e.g. redirect) in a closure (e.g. goToURL) from an external module, you'll need to mock that function. See mocking modules and mocking partials in the Jest documentation.
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