应用程序代码正在调用location.href = "some-url"
。我想编写一个测试来验证是否发生了导航重定向。
在jsdom上使用jest时,我尝试使用jest mock函数覆盖location.href setter,它正在工作。
但现在我似乎无法在测试清理时恢复location.href属性,并且它未能通过依赖于“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);
});
我错过了什么?为什么Object.getOwnPropertyDescriptor(window.location, 'href');
是undefined
?
有没有更好的方法来拦截导航事件以便对其进行测试?
谢谢
4条答案
按热度按时间tgabmvqs1#
使用location.assign()方法,而不是将新的位置字符串分配给location.href。然后,您可以模拟和测试它,没有任何问题:
cxfofazt2#
较新的jest/jsdom版本不允许再设置
window.location.assign
,可以这样修复:注意,这将从window.location中删除所有其他对象,您可能需要根据您的测试和应用程序代码来模拟它的更多对象。
来源:https://remarkablemark.org/blog/2018/11/17/mock-window-location/
rggaifut3#
正如quotesBro已经解释过的in his answer,您应该使用location.assign()。
但是从Jest v25(使用较新版本的JSDOM)开始,您将得到以下错误:
顺便说一句,这不是Jest/JSDOM的bug。这是正常的浏览器行为,JSDOM试图像真实的的浏览器一样工作。
变通方法是删除位置对象,创建自己的位置对象,并在运行测试后将其重置为原始位置对象:
2jcobegt4#
另一个非常简单的解决方案是在测试文件的开头模拟locationwindow.location对象