Checking text appears inside an element using react testing library
Asked Answered
A

3

89

I'm writing some tests for a React app using Testing Library. I want to check that some text appears, but I need to check it appears in a particular place because I know it already appears somewhere else.

The Testing Library documentation for queries says that the getByText query takes a container parameter, which I guessed lets you search within that container. I tried doing this, with the container and text parameters in the order specified in the docs:

const container = getByTestId('my-test-id');
expect(getByText(container, 'some text')).toBeTruthy();

and I get an error: matcher.test is not a function.

If I put the params the other way round:

const container = getByTestId('my-test-id');
expect(getByText('some text', container)).toBeTruthy();

I get a different error: Found multiple elements with the text: some text

Which means it's not searching inside the specified container.

I think I'm not understanding how getByText works. What am I doing wrong?

Aweless answered 21/11, 2019 at 13:32 Comment(1)
You can grab the text with expect(container.textContent).toMatch('some text')Forbearance
S
94

Better to use within for this sort of things:

render(<MyComponent />)
const { getByText } = within(screen.getByTestId('my-test-id'))
expect(getByText('some text')).toBeInTheDocument()
Shack answered 25/11, 2019 at 8:43 Comment(9)
Following up the is s solution as getByText throw out error if text cannt find. Then what is the point to use expect....toBeInTheDocument?Derick
This shouldn't be the accepted answer as from documentation: ' Avoid destructuring queries from render result, use screen.getByTestId instead'Unappealable
@carmine-tambascia, do you have a link to that quote in the docs? I can't seem to find it.Gunnel
@Gunnel develop.sentry.dev/frontend/using-rtl/….Unappealable
@carmine-tambascia Thank you. Seems it's just a tip for the sake of the developer, though, and nothing more.Gunnel
@carmine-tambascia Also, those are not the React Testing Library docs. The docs can be found here.Gunnel
@Gunnel "Seems it's just a tip for the sake of the developer," well that's what we are doing "here". On top, not sure why you are mentioning the React Testing library. the question is pretty simple.Unappealable
@carmine-tambascia The question is tagged with "react-testing-library" lol. You said this shouldn't be the accepted answer because it's not following a guide from the docs, but you quoted the Sentry docs and it was only a suggestion even there. I just wanted to make it clear to future readers this answer is okay.Gunnel
@Gunnel ok I misread regarding the Testing library, got confused regarding another issue. Nevertheless, I stand with my previous message, maybe isn't a bad answer, but neither the one to get the attention as the accepted one. That'it. let's move one, there are better things to do.Unappealable
W
84

Another way to do this

import {render, screen} from '@testing-library/react';

...

  render(<MyComponent />);
  expect(screen.getByTestId('my-test-id')).toHaveTextContent('some text');

Note it is now recommended to use screen instead of the results of render.

(StackOverflow post the points to a KC Dobbs Article explaining why: react-testing-library - Screen vs Render queries)

Woehick answered 13/10, 2020 at 14:39 Comment(6)
You may need to add import "@testing-library/jest-dom/extend-expect"; to access the toHaveTextContent matcher as described here.Telefilm
"...recommended to use screen..." But y tho? Rather than pontificating, a link by Those Who Recommend would be appreciated.Preemie
Heres another SO post on screen vs render that points to a KC Dobbs explination: #61482918Woehick
Unfortunately on toHaveTextContent I got ' Property 'toHaveTextContent' does not exist on type 'HTMLElement''Unappealable
This is simple and works perfectly for me :) thanksAlbum
Seems like a much better solution than the accepted answer, which forces a particular coding style.Gripe
G
10

This way you can be more precise, focusing in specific item:

expect(queryByTestId("helperText")?.textContent).toContain("Help me!");
Genteelism answered 19/9, 2022 at 17:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.