TypeScript 玩笑测试中的模拟 window.location

nob*_*are 5 typescript jestjs

我有一段代码,用于将重定向的完整 URL 组合在一起(类似这样):

import { redirect } from './some-utils'

export const goToURL = () => {
    const url = window.location.origin + window.location.pathname
    redirect(url)
}
Run Code Online (Sandbox Code Playgroud)

现在,我正在尝试编写一个 TypeScript 测试来测试 URL 字符串:

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')
    })
})
Run Code Online (Sandbox Code Playgroud)

但是,我收到两个 TypeScript 错误。在线上delete

“删除”运算符的操作数必须是可选的。

以及关于 的新任务window.location

输入 '{ 来源:字符串;路径名:字符串;}' 不可分配给类型'Location | (字符串和位置)'。输入 '{ 来源:字符串;路径名:字符串;}' 不可分配给类型“字符串和位置”。输入 '{ 来源:字符串;路径名:字符串;}' 不可分配给类型“string”。

我尝试通过删除语句来修复第一个错误,并尝试通过添加到作业末尾delete来修复第二个错误。as Location这样做修复了 TS 错误,但我的测试不再通过。它使用我的网络应用程序的域,而不是我的测试中的示例域。

任何人都可以帮助我修复 TS 错误,同时确保我的测试通过吗?

编辑:

如果我尝试window.location = 'https://www.example.com/mypath',我的测试仍然没有通过,并且仍然收到 TS 错误:

类型“string”不可分配给类型“Location |” (字符串和位置)'

如果我尝试window.location.href = 'https://www.example.com/mypath',TS 错误就会消失,但测试不会通过。

如果我尝试window.location.assign(https://www.example.com/mypath'),TS 错误就会消失,但测试不会通过。

jse*_*ksn 17

如果您仅使用 API 的子集(例如)Location的实例上也可用,那么您可以在测试期间手动模拟(替换)该属性:URLwindow.location.href = "https://domain.tld/pathname"window

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);
  });
});
Run Code Online (Sandbox Code Playgroud)

我故意没有解决代码的其他方面,因为这不是您所问的问题,但是如果您想从外部模块模拟redirect闭包(例如goToURL)中的函数调用(例如),您需要模拟该函数。请参阅Jest 文档中的模拟模块模拟部分。