Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Figuring out how to mock the window size changing for a react component test

So basically when the component mounts, I have an event listener listen for resize events. It toggles the isMobileView state and then passes it into the children as a prop. So it's imperative that this works and is tested. I'm fairly new to testing and I'm trying to figure out a way I can write a test that resizes the window and makes all the logic happen and test that it executed how it should.

Here is the code -

componentDidMount() {
    this.setMobileViewState()
    window.addEventListener('resize', this.setMobileViewState.bind(this));
}

setMobileViewState() {
    if(document.documentElement.clientWidth <= this.props.mobileMenuShowWidth) {
        this.setState({ isMobileView: true })
    } else {
        this.setState({ isMobileView: false })
    }
}

I know the code works, but I want to write a test for it. Basically just something that makes sure the state changes correctly.

like image 587
joe Avatar asked Aug 24 '17 17:08

joe


People also ask

How do you determine window size React?

To get the width and height of the window in React: Use the innerWidth and innerHeight properties on the window object. Add an event listener for the resize event in the useEffect hook. Keep changes to the width and height of the window in a state variable.

Does React Rerender on window resize?

We can use the useLayoutEffect to add the event listener that runs when the window resizes. And in the window resize event handler, we can run our code to change a state to make the view rerender. We create the useWindowSize hook that has the size state.


3 Answers

Using Jest and Enzyme you can do the following. Jest has JSDOM baked in. In your tests Jest provides the window object and it is represented by global (I think that the default window.innerWidth set by Jest is 1024px):

test('Test something when the viewport changes.', () => {

    // Mount the component to test.
    const component = mount(<ComponentToTest/>);

    ...

    // Change the viewport to 500px.
    global.innerWidth = 500;

    // Trigger the window resize event.
    global.dispatchEvent(new Event('resize'));

    ...

    // Run your assertion.
});
like image 159
JoeTidee Avatar answered Oct 14 '22 09:10

JoeTidee


If you are getting the typescript error message

Cannot assign to 'innerWidth' because it is a read-only property.

Try:

Object.defineProperty(window, 'innerWidth', {writable: true, configurable: true, value: 200})
like image 40
Lauren Madigan Avatar answered Oct 14 '22 11:10

Lauren Madigan


Try this line:

window = Object.assign(window, { innerWidth: 500 });
like image 41
Lital Levy Avatar answered Oct 14 '22 09:10

Lital Levy