How to get the result 'toHaveStyle' in testing-library-react?
Asked Answered
M

2

9

Testing library react does not catch 'toHaveStyle'.
When I clicked on the 'Content', its children which have a blue color were changed to the red color.

However, in my test, they always have the blue color.

What should I do to solve this problem?

[...]
<Content data-testid={"list-element-content"} id={data.id} toggle={state[data.id - 1]}>
  <div>{data.titleUnBold}</div>
  <BoldTitle>{data.titleBold}</BoldTitle>
</Content>
[...]

const Content = styled.div`
  color: ${ (props) => props.toggle ? "red" : "blue" };
`;

Below the test code:

test("color changed", () => {
  const mockState = [false];
  const mockSwitchGuide = jest.fn();
  const { getAllByTestId, rerender } = render(
    <GuideListPresenter
      data={mockListData}
      state={mockState} 
      onClick={mockSwitchGuide}
    />
  );

  act(() => {
    fireEvent.change(getAllByTestId("list-element-content")[0],{
      target: {toggle: true},
    });
  });

  rerender(
    <GuideListPresenter data={mockListData} state={mockState} onClick={mockSwitchGuide} />
  );
  expect(getAllByTestId("list-element-content")[0].toggle).toEqual(true);  // success 
  expect(getAllByTestId("list-element-content")[0]).toHaveStyle("color: red");   // failed
})
Mining answered 22/11, 2020 at 7:21 Comment(0)
S
7

To test the style of your component, you can get it directly from the html document, and see precisely what style is used for a specific element.

In your example, you would do something like below:

it('should change color to red on toggle click', () => {
  const { container, getAllByTestId } = render(
    <GuideListPresenter
      data={mockListData}
      state={mockState} 
      onClick={mockSwitchGuide}
    />
  );

  // Replace <YOUR_DIV_ID> by your component's id
  let contentDiv = document.getElementById('<YOUR_DIV_ID>');
  let style = window.getComputedStyle(contentDiv[0]);
  expect(style.color).toBe('blue'); // Sometimes, only rgb style type is read here. See the rgb that corresponds to your color if need be.

  act(() => {
    fireEvent.change(getAllByTestId("list-element-content")[0],{
      target: {toggle: true},
    });
  });

  // Get the updated contentDiv
  contentDiv = document.getElementsByClassName('<YOUR_DIV_CLASS_NAME>');
  style = window.getComputedStyle(contentDiv[0]);
  expect(style.color).toBe('red');

  expect(getAllByTestId("list-element-content")[0].toggle).toEqual(true);
}

Here, to get the style of your element, I am using the element's id. However, it could also work with the element's className, and using the method document.getElementByClassName('YOUR_DIV_CLASS_NAME') instead. Note that the given name here should be unique, either with the id technique, or the className.

Sunglasses answered 6/12, 2020 at 10:29 Comment(0)
F
3

You need to use the async findBy* queries to reliably assert changes after events.

Coupled with the @testing-library/jest-dom companion libraries toHaveStyle helper it will enables you to assert styles more easily than the accepted answer.

Flooring answered 25/5, 2023 at 7:18 Comment(1)
Yes, import '@testing-library/jest-dom' worked for me.Cooky

© 2022 - 2024 — McMap. All rights reserved.