Jest-styled-components: Checking style rules using Jest matchers

Created on 12 Jun 2018  Â·  5Comments  Â·  Source: styled-components/jest-styled-components

In Jest the expect function has many powerful matchers to work with objects, arrays and string.

You can easily make an assertion like this


expect('my custom string').toEqual(expect.stringContaining('custom'))


.toHaveStyleRule works with strings; it fetches the style (_as a string_) applied to a specific rule.
Sometimes the props passed to a component are affecting the styles applied to specific rules and it would be great to use the Jest matchers rather than just doing a comparison against the entire value.

Take the following rule example:


border: 0.05em solid ${({transparent}) => transparent ? 'transparent' : 'black'};


In my test case scenario I want to check the default styling like so:

expect(component).toHaveStyleRule('border', '0.05em solid black')

And later on I want to have another test to check the variation given a passed prop (in this case "transparent").

However this prop only changes the colour of my border so I don’t want to test against the border-width nor border-style as these are core styles that I’m already testing with my _default styling_ assertion above.
This is what I want to do:

expect(component).toHaveStyleRule('border', expect.stringContaining('transparent'))

This is just one use case but there are definitely more scenarios where Jest matchers might be useful.
For example given this rule


opacity: ${({ disabled }) => disabled && '.65'};

I want to test that by default (when not passing the "disabled" prop) my component doesn't have any opacity rule applied; with Jest matchers I could do this with either one of the following assertions:


expect(component).not.toHaveStyleRule('opacity', expect.anything())

expect(component).not.toHaveStyleRule('opacity', expect.any(String))


But this is currently not supported by .toHaveStyleRule as it expects a string to compare against the style rule.


A different way of achieving this, which might mitigate the additional responsibility for this module, would be to add a complimentary function to .toHaveStyleRule.
A function named .styleRule, for example, could just be responsible for returning a string with the style applied to a given rule and then the Jest API can be used to apply any matching logic.

Here is an example of what this could look like:

expect(component.styleRule('border')).toEqual(expect.stringContaining('transparent'))

expect(component.styleRule('opacity')).toBeUndefined() // or .toBeNull() || .toBeFalsy()


Obviously this should take the same arguments of .toHaveStyleRule and so we should be able to pass modifiers and media.

enhancement help wanted

All 5 comments

Thank you very much @santino for opening this issue.

Although is currently possible to achieve some of the behaviours you described using a regex, I really like the solution you suggested.

Do you have time to work on a PR?
I'll be happy to review it.

Hi @MicheleBertoli,
I have been looking into this and unfortunately the .styleRule approach is not feasible.

In order to have something like this


expect(component.styleRule('border')).toBe(‘something’)


styleRule would need to be a method in Enzyme and/or react-test-renderer.

Even the following approach wouldn’t work


expect(component).styleRule('border').toBe(‘something’)


Because Jest does allow creation of custom matchers but they can’t return a string; since they are matchers (and so need to implement a matching logic) they need to return an object with pass and message properties.

Given the above I went back to the original approach of supporting the jest asymmetric matchers and I will create a PR soon.
My goal is to support something like the following examples:

expect(component).toHaveStyleRule(‘border’, expect.stringContaining('transparent'))

expect(component).not.toHaveStyleRule('opacity', expect.any(String))

I have a working prototype that just needs some polishing.

Unfortunately I don’t have experience with React Native so someone else will possibly have to port my changes onto the React Native implementation of .toHaveStyleRule.

@MicheleBertoli I have now opened the pull request and I have implemented the changes also for React Native.
Hope you can review it soon as I'm keen to start using the new functionalities :)

Hey @MicheleBertoli, sorry for opening this issue again.

I was just wondering when you were planning to publish a new release to include the new features addressed following this issue.
It's been a while now and I would really need to update my project making use of Jest asymmetric matchers.

Thanks :)

Hey @santino,
I was waiting for a couple of issues (e.g. #135) to be closed and to find time for cleaning up a few things (e.g. Eslint VS Prettier) before pushing a new major.

However, I can see the value of using the current master with your changes, so I pushed: [email protected].

Feel free to install it using yarn add --dev jest-styled-components@next.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nerfologist picture nerfologist  Â·  4Comments

BenLorantfy picture BenLorantfy  Â·  3Comments

chhuang picture chhuang  Â·  6Comments

terrencewwong picture terrencewwong  Â·  6Comments

tdimnet picture tdimnet  Â·  6Comments