我正在尝试对某个视口宽度的组件进行测试。我正在做以下事情,但这似乎没有改变它:
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
答案 0 :(得分:6)
背景信息:
jsdom
does not implement window.resizeBy()
或window.resizeTo()
jsdom
defines the window innerWidth and innerHeight为1024 x 768 jsdom
事件,可以使用resize
模拟窗口调整大小这里是一个例子:
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
答案 1 :(得分:1)
如果您使用的是TypeScript,它将抱怨window.innerWidth / innerHeight是只读的。 您可以通过重新声明属性来解决此问题:
Object.defineProperty(window, 'innerWidth', {writable: true, configurable: true, value: 105})
或使用Object.assign方法:
window = Object.assign(window, { innerWidth: 105 });
这两种解决方案都不是很好,但是它们可以工作。
答案 2 :(得分:0)
为我工作。代码不再标记为已发现。
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);
...