question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Converting instance of React component to shallow wrapper

See original GitHub issue

I assume I missed some bit from documentation, but so far my searches didn’t achieve anything. Let’s say I have a very simple setup of component, which looks like this, and I want to test it:

import React, { Component } from 'react';
import Button from 'components/Button';

class MyComponent extends Component {
    render() {
    	const { shouldRenderButton } = this.props;

    	return (<div>
    	    <h1>My Amazing Title<h1>
    	    {shouldRenderButton && this.renderButton()}
    	</div>);
    }

    renderButton() {
    	return (<Button 
    	    outlined={true} 
    	    amazing={'dinosaur'}
    	/>);
    }
}

The common approach to test in react is to invoke the shallow render on the root of the component, and then start testing internals. In this particular case, this will work nice, but if your application grows, writing tests like this will become cumbersome and you will start splitting your components into additional subrenders.

The way how I want to test my component in this case, is I want to test both render and renderButton methods separately (stubbing where necessary), while still using enzyme. The reasons for doing this is a separate topic, but basically to achieve better tests, which are less fragile to other changes.

And here I’m stuck, because when invoking this code, I have no idea how to use enzyme anymore:

const wrapper = shallow(<MyComponent shouldRenderButton />;
const resultOfSubrender = wrapper.instance().renderButton();
// How to use enzyme API on the resultOfSubrender

Here’s how assertion, which I want to write looks like:

describe('renderButton', () => {
    it('should have an amazing prop of dinosaur', () => {
        const wrapper = shallow(<MyComponent shouldRenderButton />);
        const renderedButton = wrapper.instance.renderButton();
        let buttonShallowWrapper;
        // Here I do some magick with renderedButton to convert it into shallow wrapper

        // Assuming I use chai-enzyme
        // https://github.com/producthunt/chai-enzyme#propkey-val
        expect(buttonShallowWrapper).to.have.prop('amazing', 'dinosaur');
    })
})

My question is how can I convert the instance of rendered react component into a shallow wrapper, after it happened, and whether it’s even possible to do this. So far I’ve been relying on react-dom/test-utils and just direct assertions agains the properties of the instance, but it would be nice to be able to use enzyme.

If I wrap the resultOfSubrender into shallow, the returned wrapper root is actually the result of the render method of Button component, which is tested separately, and useless for my assertions agains the props I pass inside this component. Of course I could wrap my button in additional <div> and then use selector based find to get my button, but this will make me modify my markup structure just to write test, which I would prefer to avoid.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:2
  • Comments:10 (4 by maintainers)

github_iconTop GitHub Comments

6reactions
dentuzhikcommented, Apr 27, 2017

Ok, so I looked into search code, and seems like this helper does the trick: https://github.com/airbnb/enzyme/blob/master/src/ReactWrapper.jsx#L927

The result assertion will look like this:

describe('renderButton', () => {
    it('should have an amazing prop of dinosaur', () => {
        const wrapper = shallow(<MyComponent shouldRenderButton />);
        const renderedButton = wrapper.instance.renderButton();
        const buttonShallowWrapper = wrapper.wrap(renderedButton);

        expect(buttonShallowWrapper).to.have.prop('amazing', 'dinosaur');
    });
});
4reactions
d65yancommented, Feb 20, 2018

this is an old post but just wanted to say that maybe having the helper documented is not a bad idea. it would be very useful when dealing with things like Portals on React 16

Read more comments on GitHub >

github_iconTop Results From Across the Web

Shallow Rendering API - Enzyme - GitHub Pages
Returns a wrapper representing the wrappingComponent , if one was passed. .instance() => ReactComponent. Returns the instance of the root component. .update() => ......
Read more >
Shallow mock extends React.Component<MyInterface,any ...
I just wanted to know how to create instance of react component which has multiple interface inherited ShallowWrapper<InsightsComponentProps ...
Read more >
Shallow Renderer - React
Shallow rendering lets you render a component “one level deep” and assert facts about what its render method returns, without worrying about the...
Read more >
Migrate from Enzyme | Testing Library
Enzyme's shallow renderer doesn't render sub-components, so React Testing Library's render method is more similar to Enzyme's mount method. In ...
Read more >
Testing with Jest and Enzyme in React — Part 4 (shallow vs ...
shallow method is used to render the single component that we are testing. It does not render child components. In Enzyme version less...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found