J. Hesters
J. Hesters

Reputation: 14806

React testing library: Test styles (specifically background image)

I'm building a React app with TypeScript. I do my component tests with react-testing-library.

I'm buildilng a parallax component for my landing page.

The component is passed the image via props and sets it via JSS as a background image:

<div
  className={parallaxClasses}
  style={{
    backgroundImage: "url(" + image + ")",
    ...this.state
  }}
>
  {children}
</div>

Here is the unit test that I wrote:

import React from "react";
import { cleanup, render } from "react-testing-library";
import Parallax, { OwnProps } from "./Parallax";
afterEach(cleanup);

const createTestProps = (props?: object): OwnProps => ({
  children: null,
  filter: "primary",
  image: require("../../assets/images/bridge.jpg"),
  ...props
});

describe("Parallax", () => {
  const props = createTestProps();
  const { getByText } = render(<Parallax {...props} />);
  describe("rendering", () => {
    test("it renders the image", () => {
      expect(getByText(props.image)).toBeDefined();
    });
  });
});

But it fails saying:

● Parallax › rendering › it renders the image

    Unable to find an element with the text: bridge.jpg. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

    <body>
      <div>
        <div
          class="Parallax-parallax-3 Parallax-primaryColor-4"
          style="background-image: url(bridge.jpg); transform: translate3d(0,0px,0);"
        />
      </div>
    </body>

      16 |   describe("rendering", () => {
      17 |     test("it renders the image", () => {
    > 18 |       expect(getByText(props.image)).toBeDefined();
         |              ^
      19 |     });
      20 |   });
      21 | });

      at getElementError (node_modules/dom-testing-library/dist/query-helpers.js:30:10)
      at getAllByText (node_modules/dom-testing-library/dist/queries.js:336:45)
      at firstResultOrNull (node_modules/dom-testing-library/dist/query-helpers.js:38:30)
      at getByText (node_modules/dom-testing-library/dist/queries.js:346:42)
      at Object.getByText (src/components/Parallax/Parallax.test.tsx:18:14)

How can I test that the image is being set as a background image correctly with Jest and react-testing-library?

Upvotes: 68

Views: 117635

Answers (5)

Logesh B
Logesh B

Reputation: 11

I'm encountering an issue with backgroundImage in my Vite React TypeScript Jest project. When I create a project using create-react-app, everything works as expected. However, when I use Vite, the following code:

getByTestId('background').style.backgroundImage

returns url(default), instead of the expected value.

I suspect I might be missing some configuration. Is there anyone here who can assist me in resolving this issue? I'm using Vite with React, TypeScript, and Jest.

Upvotes: 0

Gio Polvara
Gio Polvara

Reputation: 27018

getByText won't find the image or its CSS. What it does is to look for a DOM node with the text you specified.

In your case, I would add a data-testid parameter to your background (<div data-testid="background">) and find the component using getByTestId.

After that you can test like this:

expect(getByTestId('background')).toHaveStyle(`background-image: url(${props.image})`)

Make sure you install @testing-library/jest-dom in order to have toHaveStyle.

Upvotes: 98

samo0ha
samo0ha

Reputation: 3796

in addition to toHaveStyle JsDOM Matcher, you can use also style property which is available to the current dom element

Element DOM API

expect(getByTestId('background').style.backgroundImage).toEqual(`url(${props.image})`)

also, you can use another jestDOM matcher

toHaveAttribute Matcher

expect(getByTestId('background')).toHaveAttribute('style',`background-image: url(${props.image})`)

Upvotes: 7

Ashish Kumar
Ashish Kumar

Reputation: 59

Simple solution for testing Component css with react-testing-library. this is helpful for me it is working perfect.

test('Should attach background color if user
      provide color from props', () => {
render(<ProfilePic name="Any Name" color="red" data- 
 testid="profile"/>);
//or can fetch the specific element from the component 
const profile = screen.getByTestId('profile');

const profilePicElem = document.getElementsByClassName(
  profile.className,
);
const style = window.getComputedStyle(profilePicElem[0]);

//Assertion 
expect(style.backgroundColor).toBe('red');
});

Upvotes: 3

Katie McCulloch
Katie McCulloch

Reputation: 394

If you want to avoid adding data-testid to your component, you can use container from react-testing-library.

const {container} = render(<Parallax {...props})/>
expect(container.firstChild).toHaveStyle(`background-image: url(${props.image})`)

This solution makes sense for your component test, since you are testing the background-image of the root node. However, keep in mind this note from the docs:

If you find yourself using container to query for rendered elements then you should reconsider! The other queries are designed to be more resiliant to changes that will be made to the component you're testing. Avoid using container to query for elements!

Upvotes: 20

Related Questions