在我的jest配置中,仅升级到jsdom-十四。效果很好,但是一次测试失败了。
test('Do the thing', () => {
window.location.assign = jest.fn();
});
我继承了这段代码。看起来像一个简单的玩笑。它抱怨无法分配只读属性assign
,这很有意义,我认为这是添加的jsdom功能。
但是...我也不能做jest.spyOn
,这似乎是建议的做法。我以前没有用过spyOn。
jest.spyOn(window.location.assign);
但这给了我一个未定义的属性错误:
Cannot spy the undefined property because it is not a function; undefined given instead
在此之前的行中,我添加了一个日志以进行检查。绝对是一个功能:
console.log(window.location.assign);
=> [Function: assign]
我不确定这两个错误如何共存-定义和未定义?
答案 0 :(得分:2)
由于JavaScript的工作方式,不可能像spyOn
那样编写spyOn(window.location.assign)
函数。在spyOn
内部,可以检索作为参数提供的window.location.assign
函数,但没有window.location
对象和assign
方法名称来提供window.location.assign = jest.fn()
。
spyOn
的签名是:
jest.spyOn(object,methodName)
应该是:
jest.spyOn(window.location, 'assign');
这可能也不可行,因为window.location.assign
在更高版本的JSDOM中是只读的,Jest使用它在Node.js中模拟DOM。该错误确认这是问题所在。
可能可以手动模拟只读属性:
const origAssign = Object.getOwnPropertyDescriptor(window.location, 'assign');
beforeEach(() => {
Object.defineProperty(window.location, 'assign', { value: jest.fn() })
});
afterEach(() => {
Object.defineProperty(window.location, 'assign', origAssign)
});
这不适用于真实的DOM,因为内置程序可能是只读的且不可配置。这是Chrome中的问题。出于可测试性的原因,使用location.href
而不是location.assign
可能是有益的。
答案 1 :(得分:1)
最终完成了一些工作,found this:
delete global.window.location;
window.location = { assign : jest.fn()};
由于后来出现的jsdom迭代将位置对象越来越向下锁定,直到它完全不可修改为止,@ Estus的答案仅在较低版本的jsdom / jest中起作用。