1
votes

I was trying to upgrade to react 16+ and my existing unit tests are failing. The application runs fine, only unit tests fails.

connected-component:

const componentsWrapper = (Components, selectData) => {

    class BaseComponent extends Component {

        constructor(props) {
            super(props);
            this.state = {
                saveMode: false,
                updateMode: false
            };
            this.foo = () => { };
        }

        render() {
          return (
              <Components
                  {...this.props}
              />
          );
        }

    }
  }

    const mapDispatchToProps = dispatch => {
        return selectData.getDispatch(dispatch);
    };
    const mapStateToProps = state => {
        return selectData.getStore(state);
    };

    return connect(mapStateToProps, mapDispatchToProps)(BaseComponent);
};

export default componentsWrapper;

unit test:

class MockListComponent extends Component {
  render() {
      return (<div>Fake List</div>);
  }
}
Components = componentsWrapper(MockListComponent, selectComponents);
wrapper = shallow(<Components store={store} />).dive();
instance = wrapper.instance()
// Here instance is null hence the rest will fail.
instance.foo = jest.fn();

instance is null because "Connect" component is functional or stateless. Source

NOTE: With React 16 and above, instance() returns null for stateless functional components.

I don't know how to get the instance to not be null or maybe refactor the code. I appreciate any help or hint.

These are the library versions I am trying to use: [email protected] [email protected] [email protected]

1
Hey there, did my solution solve your issue? - wentjun
@wentjun Yes, the trick was to export them (component and connected-component) separately - Node.JS

1 Answers

1
votes

I am not sure what is the exact behaviour you are trying to test, but in many cases, there is no need to explicitly 'test' the entire connected component unless you are planning to do integrated testing or functional testing.

To fix the issue you are facing, I would recommend you to export the child component (take note of export on BaseComponent):

const componentsWrapper = (Components, selectData) => {

  export class BaseComponent extends Component {

   // ... rest of the logic

  }

}

Then, on your test file, we use enzyme's .find() to find the node that matches the selector. In this case, our selector is BaseComponent.

const wrapper = shallow(<Components store={store} />)
const wrapperInstance = wrapper.dive().find(BaseComponent).instance();

From there, you will have access to BaseComponent's class instance, and you can use it to call its methods, or spy on its methods.


The reason why you are facing the error stated on the question is explained on the enzyme documentation:

With React 16 and above, instance() returns null for stateless functional components.

Therefore, you can only call .instance() on the component itself, rather than the entire connected component.