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.
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:
Did you find this post useful?
Let me know by sharing it on Twitter.If you to learn more about testing React apps, you may find my course useful: