Integration test a React component that consumes a Render Prop

Share this video with your friends

Send Tweet
Published 4 years ago
Updated 10 months ago

In this lesson, I use Enzyme and Jest's Snapshot functionality to write an integration test for a component called CounterConsumer that consumes the Render Prop component Counter. This integration test is great because it doesn't necessarily care that CounterConsumer uses Counter behind the scenes, just that it works when integrated.

Other resources: Testing ⚛️ components using render props

Instructor: [00:00] I have a counter component I'd like to test. This component can increment, decrement, and accepts an initial value. In my code, you'll notice that I'm rendering something called a counter consumer. This component is actually using a render prop component called counter to pass in functionality to our rendered component.

[00:22] If we look at our counter render prop component, you'll notice that we have state for our counter. We can pass it an initial property. We have two methods, one for increment and decrement. Then what we do is we pass our methods and our state to our render prop function which is children in this case.

[00:38] Now that we know how our component works, I'm going to write an integration test which will essentially test my counter consumer component along with my counter render prop component. For this example, I'll be using snapshot testing with Jest paired with Enzyme. But you can easily do this with React Test Renderer and a search specific value. It whatever makes you happy and gets the job done.

[00:56] First, we'll need to import our counter consumer. Since our counter consumer component accepts an initial value, let's test that first. It accepts an initial value, const wrapper equals mounts. We'll pass our counter a consumer to it and pass an initial value. Now for our assertion. Let's say expect to JSON wrapper to match snapshot. Let's make sure our tests are running. Looks good.

[01:28] Now to look at our snapshot. As we can see here, that we are passing an initial value to our counter and that it is rendering our initial value of 1,999. This test is passed and is looking good.

[01:40] Now to test our increment and our decrement buttons. Let's copy our first test, paste it here. We'll remove the initial value. We'll say it increments counter. We'll say wrapper find button at zero which is our first button. We'll simulate a click. Now to look at our snapshot again. It looks like our counter is indeed incrementing. It went from a zero to a one. Our snapshot is right.

[02:13] Now to test the decrement button, we'll copy what we have here, paste it, decrements counter. We'll say at one, which is the second button in our component, the decrement, save, make sure our tests are good. We'll go ahead and look at our snapshot. As you can see, our decrement button is indeed decrementing. We went from zero to negative one.

[02:39] Something to notice is how integration testing components that consume a render prop doesn't look much different than testing a normal component. At this point, the render prop is an implementation detail, hidden away, and we don't really care how we're getting rendered output, just that it's correct.

[02:56] In many cases, we can infer that the counter component works because the counter consumer works. Unit testing can be a bit more complex but doable. I personally find in most cases the integration test is good enough.