In this post I will present you a quick guide how to test React components which use Apollo.
At first let's see how our component looks like:
import React from 'react'
import gql from 'graphql-tag'
import { useQuery } from '@apollo/react-hooks'
export const POSTS_QUERY = gql`
query Post($id: String!) {
{
post(id: $id) {
title
author
description
}
}
}
`
const Post = ({ postId )} => {
const { loading, error, data } = useQuery(POSTS_QUERY, {
variables: { id: postId },
})
if (loading) return null
if (error) return `Error: ${error}`
return (
<div>
<h3 data-testId="post-title">{data.post.title}</h3>
<h4 data-testId="post-author">{data.post.author}</h4>
<p data-testId="post-description">{data.post.description}</p>
</div>
)
}
export default Post
I always had issues with testing components which do not render desired value immediately. In our case Post component at first won't render anything, because it is in loading
state.
Fortunately react-testing-library
solves this problem for us. It allows us to wait for some element to be rendered.
On the other hand, Apollo has very useful MockedProvider
component. Thanks to this component you can mock result of your queries. Let's take a look at the code.
import React from 'react'
import { render, cleanup, findByTestId, findByText } from '@testing-library/react'
import { MockedProvider } from '@apollo/react-testing'
import Post, { POSTS_QUERY } from './Post'
const mocks = [
{
request: {
query: POSTS_QUERY,
variables: {
id: 'postId',
}
},
result: {
data: {
post: {
title: 'title',
author: 'author',
description: 'description',
}
}
}
}
]
describe('Post', () => {
afterEach(cleanup)
it('should render post title', async () => {
const { container ) = render(
<MockedProvider mocks={mocks} addTypename={false}>
<Post postId="postId" />
</MockedProvider>
)
const titleElement = await findByTestId(container, 'post-title')
const titleContent = await findByText(titleElement, 'title')
expect(titleElement).toBeTruthy()
expect(titleContent).toBeTruthy()
})
...tests for author and description
})
At first we create mocked query response for POSTS_QUERY
. We pass the mocks
variable to MockedProvider
when rendering our component.
To get title element we use findByTestId
function. When you go back to component code you can see we added data-testId
to h3
element.
When we finally find this element we check whether it has expected text using findByText
.
Additional resources
Apollo Docs - Testing React components
React Testing Library Docs
I'm regularly publishing my insights on web development.
Consider subscribing to my newsletter.
Visit my blog at slawkolodziej.com to find out more interesting content.
Follow me on Twitter.
Top comments (1)
Amazing article! I just found a typo.
const { container ) -> const { container }