Jest / Enzyme - How to test at different viewports?

前端 未结 3 1246
余生分开走
余生分开走 2021-01-03 22:45

I am trying to run a test on a component at a certain viewport width. I am doing the following, but this doesn\'t seem to change it:

test(\'Component should          


        
相关标签:
3条回答
  • 2021-01-03 23:14

    If you're using TypeScript it will complain that window.innerWidth/innerHeight are readonly. You can get around this with either redeclaring the property:

    Object.defineProperty(window, 'innerWidth', {writable: true, configurable: true, value: 105})
    

    or using the Object.assign method:

    window = Object.assign(window, { innerWidth: 105 });
    

    Both not extremely nice solutions, but they work.

    0 讨论(0)
  • 2021-01-03 23:18

    Background Information:

    • jsdom does not implement window.resizeBy() or window.resizeTo()
    • jsdom defines the window innerWidth and innerHeight to be 1024 x 768
    • It is possible to simulate a window resize using jsdom by manually setting window.innerWidth and window.innerHeight and firing the resize event

    Here is an example:


    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>');
      });
    });
    

    Notes:

    • As of Enzyme v3 shallow calls React lifecycle methods like componentDidMount() so it can be used in place of mount
    • This answer borrows heavily from the information here, here, here, and @JoeTidee's own answer here.
    0 讨论(0)
  • 2021-01-03 23:22

    Works for me. Code is no longer marked as uncovered.

    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();
    });
    

    Resize listener inside my component

    ...
     resizeListener = () => {
          if (window.innerWidth < 768) {
            this.setState({
              mobileMode: true
            });
          } else {
            this.setState({
              mobileMode: false
            });
          }
        };
        window.addEventListener('resize', resizeListener);
    ...
    
    0 讨论(0)
提交回复
热议问题