Verifying children passed to React mock components
Tags: javascript, react, testing
Published: 2020-09-07 20:20:49

---
title: Verifying children passed to React mock components
published: true
description: Mocks aren’t evil! They can help you build simpler, more resilient tests. Here’s a guide to using mocks well.
tags: javascript, react, testing 
series: Mocking React components with Testing Library
---

This is the third part in a series on React testing. In the last part, we looked at [the basic form of React component mocks](https://dev.to/d_ir/the-basic-form-for-react-component-mocks-g5).

Another thing you might want to do with mocks is test that it has the correct children passed. That’s what we’ll look at now.

---

_All the code samples for this post are available at the following repo._

{% github dirv/mocking-react-components %}

---

Imagine that we want to inset a mailing list sign up form inside of the `PostContent`. We can do that by passing children elements to it.

Here’s the newly improved `BlogPage` component:

```javascript
export const BlogPage = ({ url }) => {

  const id = getPostIdFromUrl(url)

  const handleSignUp = () => {
    // ...
  }

  return (
    <PostContent id={id}>
      <input type="email" placeholder="Sign up to my mailing list!" />
      <button onClick={handleSignUp}>Sign up</button>
    </PostContent>
  )
}
```

Crucially, our `BlogPage` tests shouldn’t care _what_ `PostContent` does with the children. They should just care that it was given the children.

We could test this by pulling out the `children` prop from the `.mock.calls` entry and then rendering it with `render`. In other words, treating it like a render prop.

But there’s a more straightforward way, which is to modify the mock component to render its `children`:

```javascript
jest.mock("../src/PostContent", () => ({
  PostContent: jest.fn(({ children }) => (
    <div data-testid="PostContent">{children}</div>
  ))
}))
```

Now we can write a test that checks that a `button` was rendered as a child of `PostContent`:

```javascript
it("renders the mailing list sign up button as a child of PostContent", () => {
  render(<BlogPage url="http://example.com/blog/my-web-page" />)

  const postContentElement = screen.getByTestId("PostContent")

  const button = screen.queryByRole(
    "button", { name: "Sign up" })

  expect(postContentElement).toContainElement(button)
})
```

The same technique can be repeated for the `input` field.

If you run this test, you’ll notice a problem. Our previous test that checks the passed props is now failing. Its expectation looked like this:

```javascript
  expect(PostContent).toHaveBeenCalledWith(
    { id: postId },
    expect.anything())
```

It’s failing because all of a sudden we have a `children` prop, which is unexpected according to this test.

We fix that using `expect.objectContaining`.

###Use `expect.objectContaining` to narrow down your tests

---

It’s often useful to have multiple unit tests for a single mock component call! I usually start with one test, with all props specified. But for any prop values of sufficient complexity, it can be useful to split that out into a test of its own with a good test description. The `children` prop is a special case of that: our test that checks we pass the right ID is independent of anything to do with the displaying inset content.

---

We can avoid testing `content` by using `expect.objectContaining` in our expectation:

```javascript
  expect(PostContent).toHaveBeenCalledWith(
    expect.objectContaining({ id: postId }),
    expect.anything())
```

##More lessons

So what have we learned now?

* To test children passed to mocks, modify the mock component to be `jest.fn(({ children }) = <div data-testid="ComponentName">{children}</div>)
* Use `toContainElement` from the `jest-dom` matchers package to check that components are rendered as children of your mocked component.
* Use `expect.objectContaining` to write unit tests that don’t break when your props change.
* Use Jest’s `clearMocks` configuration setting to ensure your spies are cleared before each test.

In part 4, we’ll see how we go about [testing multiple rendered instances of the same mock component](https://dev.to/d_ir/testing-multiple-instances-of-the-same-mocked-component-c16).