模板,传单,单元测试组件,给出类型错误:无法读取未定义的属性"deviceXDPI"



因此,我们正在开发一个Stenciljs组件,该组件封装传单地图并添加一些附加功能。

现在很明显,我们不想也不需要测试传单,而是只测试包装器组件中的部分。

因此,使用测试示例,我们创建了我们的测试,

import { LeMap } from "./le-map";
describe("Map component tests", () => {
it("Should build the map component", async () => {
const map = new LeMap();
expect(map).not.toBeNull();
});     
});

尝试加载组件并测试公共功能,但我们得到了

TypeError: Cannot read property 'deviceXDPI' of undefined
> 1 | import {Component, Element, Listen, Method, Prop, Watch} from 
'@stencil/core';
> 2 | import L from 'leaflet';
| ^
3 |
4 | @Component({
5 |       shadow: false,

我们认为这条消息是因为测试试图呈现传单,而且因为它不是一个真正的浏览器,它无法检测到视图,所以抛出了这个错误,所以我们试图在测试中模拟传单,但仍然遇到了同样的问题。

我们试图通过使用笑话嘲笑来嘲笑传单模块

jest.genMockFromModule('leaflet');

但这与没有区别

我唯一的想法是将逻辑从组件中分离出来,但这感觉不对,因为我们这样做只是为了测试。

正在使用的版本是:传单:1.3.4,@模版:0.15.2,笑话:23.4.2

还有其他建议吗?

感谢@skyboyer的建议,进一步的调查使我找到了这行传单的核心浏览器.js文件

引导我到这行传单核心浏览器.js文件

export var retina = (window.devicePixelRatio || (window.screen.deviceXDPI/window.screen.logicalXDPI)) > 1;

但是我无法模拟窗口的屏幕属性,因为我得到了以下错误

[ts] Cannot assign to 'screen' because it is a constant or a read-only property, 

所以我尝试以下方法。

const screen =  {
deviceXDPI:0,
logicalXDPI:0
}
Object.defineProperty(window, 'screen', screen);
Object.defineProperty(window, 'devicePixelRatio', 0);

同样的错误,完全忽略了这一点,所以我尝试绕过导出。

jest.spyOn(L.Browser,'retina').mockImplementation(() => false);

也没有快乐,所以尝试

L.Browser.retina = jest.fn(() => false); 

但get it告诉我它是一个常数,不能改变(但含义统计var so’_(ツ)_/

还有什么我可以试试的吗?

进一步更新,我已经设法模拟了窗口,但遗憾的是,这并不能解决问题

const screenMock = {            
deviceXDPI: 0,
logicalXDPI: 0          
}
const windowMock = {
value: {
'devicePixelRatio': 0,
'screen': screenMock
}
}
Object.defineProperty(global, 'window', windowMock);

如果我控制台记录这一点,我会得到正确的属性,但一旦我测试了组件的实例化,它就会在中失败

TypeError: Cannot read property 'deviceXDPI' of undefined

四处阅读,传单似乎没有检查DOM,只是尝试渲染,我看不到,我看到了一个传单无头包,但我不知道如何将它们交换出来进行测试。

我想我需要考虑另一种测试策略,可能是量角器。

找到了一个尚未完全测试的解决方案,但测试通过了。我创建了一个

__mocks__ 

目录与node_modules目录处于同一级别。创建了一个名为leaflet.js的文件。它只是包含一个简单的文件。

'use strict';
const leaflet = jest.fn();
module.exports = leaflet;

然后在我的测试文件(le-map.spec.ts(中,我刚刚添加了

jest.mock('leaflet')

进口之前

现在我的测试通过了。

我在测试中尝试过这样做,但这只是给了我同样的错误,它一定是加载序列中的某个东西,这意味着它必须事先手动模拟。

希望这能帮助到其他人,这已经让我发疯好几个星期了。

最新更新