9

Im wondering if putting new class name into html component only for readability and tests is ok. Let's say we have this situation:

class ComponentOne extends React.Component {

    render(){
        <div>
           <div>
              <div className="lower">
                 {sometext}
              </div>
            </div>
        </div>
    }

}

This classes are here only for better readability in browser and for better testing this component. Like this :

import { render } from '@testing-library/react'
it("Testing ComponentOne", ()=>{
   const { container } = render(<Component/>)
   const element = container.querySelector(".lower") // cleaner element searching
   // testing element's text here
})

Is it a bad idea to using "empty" class in React only for readability/debugging/testing ? What is the best way to find elements while testing ?

mhan
  • 121
  • 1
  • 2
  • 5
  • I try pretty hard not to do it. If there's no text content or something else I can easily match with an existing RTL matcher than I wonder if I'm _really_ trying to test UI/UX or if I'm actually testing an implementation detail. – Nick Jul 11 '21 at 20:55
  • Ok, so if i have some nested html tags, without any pointers, and i want to test changing style on click of the most nested of it i should go for the css selector/ xpath or something else ? The point is that if something will change whole selector should be changed, but if i have some classes (etc) tests wont change if structure will change. – mhan Jul 11 '21 at 21:21

2 Answers2

3

If some one looking for a solution to select by Id or Class in React Testing Library with Screen.
Then check this

class ComponentOne extends React.Component {
    render(){
        <div data-testid='main-component'>
           <div>
              <div className="lower">
                 {sometext}
                 <span id='spanid'> sometext2</span>
                 <div className="lower2">
                    {sometext3}
                 </div>
              </div>
            </div>
        </div>
    }
}

Then we can achieve this:

  import { render } from '@testing-library/react'
        it("Testing ComponentOne", ()=>{
           render(<Component/>)
    // testing element's text here
           const element = screen.getByTestId('main-component').querySelector(".lower") //select lower div
           expect(element).toHaveTextContent('sometext') 
    //Testing with Id
           const spanElement = screen.getByTestId('main-component').querySelector("#spanid") //select lower div
           expect(spanElement).toHaveTextContent('sometext2') 
    //Testing with nested class 
           const nestedElement = screen.getByTestId('main-component').querySelector(".lower.lower2") //select lower2 div
           expect(nested).toHaveTextContent('sometext3') class 
        })

You can test any class or Id base test by add a data-testid to the parent div on component level or by adding the test id in each required tags.
Then getByTestId & querySelector
I hope it will help you.

Bibhudatta Sahoo
  • 4,808
  • 2
  • 27
  • 51
1

You can use document.querySelector(...) to query anything that has been mounted. See the example below.

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

describe('Query by ID', () => {
  it('Using querySelector', async () => {
    render(
      <div className="componentClassName" id="componentId">
        component
      </div>
    );
    const component = document.querySelector('#componentId');

    expect(component).toHaveClass('componentClassName');
  });
});

jdouitsis
  • 59
  • 6