25

I want to check if inside my component exists a button.

import React, {useState} from 'react';

const Text = ({text}) => {
    const [state, setState]= useState(0);

    const add  = () => {
        setState(state+1)
    };

    return (
        <div>
            <h1>Hello World</h1>
            <h2>Hello {text}</h2>
            <h2>Count {state}</h2>
            <button role="button" onClick={add}>Increase</button>
        </div>
    );
};

export default Text;

For that test i created:

test('check counter', ()=> {
    const { getByText } = render(<Text />);
    const button = getByText("Increase");
    expect(button.toBeTruthy())
});

After running the test i get TypeError: button.toBeTruthy is not a function. Why this errror appears and how to solve the issue?

3 Answers 3

39

You have a mistake; The toBeTruthy() is not a function from the button is a function from the expect method.

  test('check counter', ()=> {
    const { getByText } = render(<Text />);
    const button = getByText("Increase");
    expect(button).toBeTruthy()
});
Sign up to request clarification or add additional context in comments.

1 Comment

24

Just one short note on how to improve this a little bit. Instead of using toBeTruthy() jest-dom utility library provides the .toBeInTheDocument() matcher, which can be used to assert that an element is in the body of the document, or not. This can be more meaningful than asserting truthfulness in this case.

Also it would be better to get the button by role instead of text since it is a preferable way by priority.

  test('check counter', ()=> {
    const { getByRole } = render(<Text />);
    const button = getByRole('button');
    expect(button).toBeInTheDocument()
});

1 Comment

Your must import '@testing-library/jest-dom';
6

I would suggest a better way to test this would be to make use of the "data-testid" attribute for the element

<div>
            <h1>Hello World</h1>
            <h2>Hello {text}</h2>
            <h2>Count {state}</h2>
            <button role="button" data-testid="required-button" onClick={add}>Increase</button>
</div>

test('check counter', ()=> {
    const { getByTestId } = render(<Text />);
    const button = getByTestId("required-button");
    expect(button).toBeInTheDocument();
});

The reason i would do this is getByText would be true for any occurrence of the word Increase in the page

7 Comments

getByTestId should be used as little as possible testing-library.com/docs/guide-which-query
Thank You @Hylle that was a good read ,i was not aware of that , however it would be great if they could mention the reson behind those guidelines
@Hylle it says on the first line of the page, "your test should resemble how users interact with your code". A user uses text to navigate and find elements to interact with, not testId attributes.
Yeah that does make sense , but don't you feel that using the Test Id is a more fundamental approach while achieving equal results
I feel like I disagree with their guidelines. Not using test IDs leads to less robust tests, as the text can change with time as your company's legal or translation department may decide the button should say something else.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.