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() jsdomdefines 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 中运行时,windowjsdom 提供的对象,其innerHeight 属性是普通属性。我猜你会得到这是一个 TypeScript 错误,在这种情况下,你可能需要使用类型断言来告诉 TypeScript 该属性不是只读的。

以上是关于Jest / Enzyme - 如何在不同的视口进行测试?的主要内容,如果未能解决你的问题,请参考以下文章

如何测试从 mapDispatchToProps 传递的函数(React/Redux/Enzyme/Jest)

如何使用 JEST、Enzyme 在 React 中测试自定义钩子?

如何使用 Jest 和/或 Enzyme 获取嵌套在 React 组件中的元素的属性?

如何使用 Jest/Enzyme 在 React 中测试文件类型输入的更改处理程序?

如何使用 Jest/Enzyme 测试去抖功能?

如何使用 Jest - Enzyme 测试 React 中 mapStateToProps 中的方法