Carl Rippon

Building SPAs

Carl Rippon
BlogBooks / CoursesAbout
This site uses cookies. Click here to find out more

Testing Emotion Styles

March 02, 2022
reacttests

Emotion is a popular CSS-in-JS library for React. One of the things I love about it is the ability to declare conditional styles directly on the component using the css prop.

Conditional styles contain logic that we may want to cover in our component tests. This post covers how to do this.

Testing Emotion Styles

A component with conditional styles

Here’s a Button component with a conditional background colour. The condition is dependent on whether it is a primary button or not:

type Props = React.ComponentPropsWithoutRef<"button"> & {
  primary?: boolean;
};
export function Button({ primary, ...rest }: Props) {
  return (
    <button
      css={css`
        ...
        background-color: ${primary
          ? "#228be6"
          : "#868e96"};
      `}
      {...rest}
    ></button>
  );
}

Trying to test a conditional style

We will attempt to write a test to check that the correct background colour is rendered when the primary prop is passed. Here’s a first attempt:

test("Should render correct background colour when primary specified", () => {
  render(<Button primary>test</Button>);
  const button = screen.getByText("test");
  expect(button.style.backgroundColor).toBe("#228be6");
});

This doesn’t work though. 😟

Emotion doesn’t set the style attribute - instead, it creates a CSS class and sets the class prop.

Using @emotion/jest

Fortunately, there is a @emotion/jest library that can help us check Emotions styles.

We install it using a terminal as follows:

npm install --save-dev @emotion/jest

@emotion/jest contains a matcher called toHaveStyleRule that we can use to check specific CSS properties.

In the test file, we import the matchers from @emotion/jest and make these available to the tests:

...
import { matchers } from "@emotion/jest";

expect.extend(matchers);
...

We can now refactor the test to use toHaveStyleRule:

test("Should render correct background colour when primary specified", () => {
  render(<Button primary>test</Button>);
  const button = screen.getByText("test");
  expect(button).toHaveStyleRule("background-color", "#228be6");
});

The test passes. ☺️

A second test for a non-primary button is as follows:

test("Should render correct background colour when primary not specified", () => {
  render(<Button>test</Button>);
  const button = screen.getByText("test");
  expect(button).toHaveStyleRule("background-color", "#868e96");
});

Nice. 😀

The code from this post is available in Codesandbox in the link below:

🏃 Play with the code

Did you find this post useful?

Let me know by sharing it on Twitter.
Click here to share this post on Twitter

If you to learn more about testing React apps, you may find my course useful:

Testing React Apps with Jest and React Testing Library

Testing React Apps with Jest and React Testing Library
Find out more