enzyme-adapter-preact-pure icon indicating copy to clipboard operation
enzyme-adapter-preact-pure copied to clipboard

shallow renders which return `null` cannot have setState called on them

Open mq2thez opened this issue 4 years ago • 2 comments

Tested in v2.2.1 and v3.0.0.

Example test case:

    it("renders", () => {
        class Tester extends React.Component {
            state = { show: false };
            render() {
                if (this.state.show) {
                    return <div>Hello</div>;
                }

                return null;
            }
        }

        const wrapper = shallow(<Tester />);
        expect(wrapper.find("div")).not.toExist();
        wrapper.setState({ show: true }); // throws Error: Method “setState” is meant to be run on 1 node. 0 found instead.
        expect(wrapper.find("div")).toExist();
    });

When working with the React v15 adapter, wrapper is a ShallowWrapper with a length of one, where the single value is a null. This allows me to call setState and update it. Using enzyme-adapter-preact-pure, wrapper has a length of zero, with no elements associated with it.

mq2thez avatar Jan 12 '21 00:01 mq2thez

In general, an enzyme mount wrapper is around the thing you're wrapping, but a shallow wrapper is around the thing the wrapped component renders. In this case, wrapper should only be wrapping around null, and setState should indeed point to the root - which is the Tester element - and not to the null.

ljharb avatar Jan 12 '21 00:01 ljharb

Thanks for the report. I'd be happy to accept a fix for this.

I should note though that both myself and the React team no longer recommend the use of shallow rendering as a method of unit test isolation. I wrote about the reasons for this and alternatives here: https://robertknight.me.uk/posts/shallow-rendering-revisited/. I intend to continue supporting it in the adapter for the foreseeable future, but be aware that it doesn't get as much attention paid to it either in React or in Preact as alternatives. The React team have removed most mentions of it from their docs and at some point we'll likely do the same.

robertknight avatar Jan 12 '21 09:01 robertknight