Jest / Enzyme - 如何在不同的视口进行测试?
Posted
技术标签:
【中文标题】Jest / Enzyme - 如何在不同的视口进行测试?【英文标题】:Jest / Enzyme - How to test at different viewports? 【发布时间】:2018-02-23 13:29:39 【问题描述】:我正在尝试在某个视口宽度的组件上运行测试。我正在执行以下操作,但这似乎并没有改变它:
test('Component should do something at a certain viewport width.', () =>
global.innerWidth = 2000;
const component = mount(<SomeComponent />);
...
);
我还找到了一篇解释如何使用 JSDom 的文章,但由于 Jest 现在附带 JSDom,我想知道是否有本地解决方案。
https://www.codementor.io/pkodmad/dom-testing-react-application-jest-k4ll4f8sd
【问题讨论】:
【参考方案1】:如果你使用 TypeScript,它会抱怨 window.innerWidth/innerHeight 是只读的。 您可以通过重新声明属性来解决此问题:
Object.defineProperty(window, 'innerWidth', writable: true, configurable: true, value: 105)
或使用 Object.assign 方法:
window = Object.assign(window, innerWidth: 105 );
这两种解决方案都不是很好,但它们都有效。
【讨论】:
但是你可以用 //@ts-ignore 注释【参考方案2】:为我工作。代码不再标记为未覆盖。
it('resize event listener changes the state', () =>
const wrapper = shallow(<Component />);
const instance = wrapper.instance();
instance.setState(
mobileMode: true
);
global.innerWidth = 800;
window.dispatchEvent(new Event('resize'));
expect(instance.state.mobileMode).toBeFalsy();
global.innerWidth = 600;
window.dispatchEvent(new Event('resize'));
expect(instance.state.mobileMode).toBeTruthy();
);
在我的组件中调整监听器的大小
...
resizeListener = () =>
if (window.innerWidth < 768)
this.setState(
mobileMode: true
);
else
this.setState(
mobileMode: false
);
;
window.addEventListener('resize', resizeListener);
...
【讨论】:
【参考方案3】:背景资料:
jsdom
does not implement window.resizeBy()
或 window.resizeTo()
jsdom
defines the window innerWidth and innerHeight 为 1024 x 768
可以通过手动设置 window.innerWidth 和 window.innerHeight 并触发 resize
事件来模拟使用 jsdom
调整窗口大小
这是一个例子:
comp.js
import * as React from 'react';
export default class Comp extends React.Component
constructor(...args)
super(...args);
this.state = width: 0, height: 0
updateDimensions = () =>
this.setState( width: window.innerWidth, height: window.innerHeight );
componentDidMount()
this.updateDimensions();
window.addEventListener("resize", this.updateDimensions);
componentWillUnmount()
window.removeEventListener("resize", this.updateDimensions);
render()
return <div>this.state.width x this.state.height</div>;
comp.test.js
import * as React from 'react';
import shallow from 'enzyme';
import Comp from './comp';
const resizeWindow = (x, y) =>
window.innerWidth = x;
window.innerHeight = y;
window.dispatchEvent(new Event('resize'));
describe('Comp', () =>
it('should display the window size', () =>
const component = shallow(<Comp />);
expect(component.html()).toEqual('<div>1024 x 768</div>');
resizeWindow(500, 300);
expect(component.html()).toEqual('<div>500 x 300</div>');
resizeWindow(2880, 1800);
expect(component.html()).toEqual('<div>2880 x 1800</div>');
);
);
注意事项:
截至Enzyme
v3 shallow
calls React lifecycle methods like componentDidMount()
所以它可以用来代替mount
此答案大量借鉴here、here、here 和@JoeTidee 自己的答案here 的信息。
【讨论】:
有没有办法处理Cannot assign to 'innerHeight' because it is a read-only property.
?
@kb_ 当测试在Jest
中运行时,window
是jsdom
提供的对象,其innerHeight
属性是普通属性。我猜你会得到这是一个 TypeScript 错误,在这种情况下,你可能需要使用类型断言来告诉 TypeScript 该属性不是只读的。以上是关于Jest / Enzyme - 如何在不同的视口进行测试?的主要内容,如果未能解决你的问题,请参考以下文章
如何测试从 mapDispatchToProps 传递的函数(React/Redux/Enzyme/Jest)
如何使用 JEST、Enzyme 在 React 中测试自定义钩子?
如何使用 Jest 和/或 Enzyme 获取嵌套在 React 组件中的元素的属性?