Testing Emotion Styles


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:

Terminal window
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

Learn React with TypeScript - 3rd Edition

New

A comprehensive guide to building modern React applications with TypeScript. Learn best practices, advanced patterns, and real-world development techniques.

View on Amazon
Learn React with TypeScript - Third Edition