Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

styled function getting wrong theme object in Jest tests #30081

Closed
2 tasks done
michaelfaith opened this issue Dec 6, 2021 · 14 comments
Closed
2 tasks done

styled function getting wrong theme object in Jest tests #30081

michaelfaith opened this issue Dec 6, 2021 · 14 comments
Labels
status: waiting for author Issue with insufficient information

Comments

@michaelfaith
Copy link

Duplicates

  • I have searched the existing issues

Latest version

  • I have tested the latest version

Current behavior 😯

I've just migrated one of my components from JSS to the styled components, as described on the migration page. Everything works fine in storybook, and the correct (custom) theme object is being applied. But when running unit tests, if I check applied styles to the rendered component, it's not getting the custom theme. It only ends up with the default theme object within styled.

Expected behavior 🤔

Should pass in correct theme object in Jest environment.

Steps to reproduce 🕹

Steps:

  1. Create custom theme using createTheme
  2. Create component using styled and use elements from the theme within the styles
  3. Test applied styles in a Jest unit test, using toHaveStyle by wrapping the component in a ThemeProvider with the custom theme and rendering with @testing-library/react.

Context 🔦

We need to be able to test that the correct colors are being applied, depending on if it's dark or light theme, and under different breakpoints.

Your environment 🌎

System:
OS: Windows 10 10.0.18363
Binaries:
Node: 14.17.0 - C:\Program Files\nodejs\node.EXE
Yarn: 1.22.15 - ~\AppData\Roaming\npm\yarn.CMD
npm: 7.18.1 - ~\src\quantum\node_modules.bin\npm.CMD
Browsers:
Chrome: 96.0.4664.45
Edge: Spartan (44.18362.1593.0)

@michaelfaith michaelfaith added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Dec 6, 2021
@siriwatknp
Copy link
Member

It doesn't look like this bug report has enough info for one of us to reproduce it.

Please provide a CodeSandbox (https://material-ui.com/r/issue-template-latest), a link to a repository on GitHub, or provide a minimal code example that reproduces the problem.

Note: from what you describe, you are testing component style in different breakpoints. I suggest you checkout chromatic which is a tool from the storybook team for visual testing. I think it will give you more confidence than using Jest. Feel free to neglect my suggestion if you already have considered it.

@siriwatknp siriwatknp added status: waiting for author Issue with insufficient information and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Dec 7, 2021
@michaelfaith
Copy link
Author

@siriwatknp thanks for the reply. My mention of breakpoints was more of a detail about my use, than an issue. The problem is that the theme object that's coming into the styled function isn't the theme passed into the MUI ThemeProvider when running jest tests. It's just the default theme object. I've had to work around it, by creating a wrapper function that passes in the theme returned from the useTheme hook instead. What's weird is that in action, when running in storybook it all works fine. But in Jest it's just the defaults. I'll try and mock up a repro to share. I encountered this on a private codebase in my company.

@mnajdova
Copy link
Member

mnajdova commented Dec 7, 2021

@michaelfaith make sure you use the ThemeProvider coming from @mui/material/styles.

@michaelfaith
Copy link
Author

michaelfaith commented Dec 7, 2021

@michaelfaith make sure you use the ThemeProvider coming from @mui/material/styles.

Thanks. Yeah, I double checked and we're definitely using the correct import path. I tried to recreate it in the codesandbox (https://codesandbox.io/s/mui-styled-issue-mpk2u?file=/src/Demo.tsx), but couldn't get it to fail there. I even used our tsconfig settings and jest.config. When that worked. I created the same demo component in our project, to see if that simple case would work, and it still doesn't. So there's something about our setup that causes this exact same code to not work on the jest side of things (the theme coming in from styled is just the default). Any suggestions on where I might dig into for that? Our project isn't that complicated, so this is somewhat befuddling.

@siriwatknp
Copy link
Member

Any suggestions on where I might dig into for that?

Can you provide the link to the repo?

@michaelfaith
Copy link
Author

michaelfaith commented Dec 8, 2021

Any suggestions on where I might dig into for that?

Can you provide the link to the repo?

The code sandbox is here: https://codesandbox.io/s/mui-styled-issue-mpk2u?file=/src/Demo.test.tsx
The repo for the project I'm experiencing the issue is in our corporate repos, and unfortunately not shareable. I tried setting that sandbox up with a boiled down version of what I'm trying to do, and replicate the config that I figured would affect this, but couldn't recreate it. The only thing I wasn't able to do in the sandbox, that we have in our project is this jest mock in the jest.setup.ts, to help with consistent snapshotting. (recommended here: #21293 (comment))

jest.mock('@mui/utils/useId', () => jest.fn().mockReturnValue('mui-test-id'));

codesandbox doesn't appear to support jest.mock like that. Do you think that could impact this? I'll try it without that when I login in the morning and see if that helps. But I'm really grasping at straws at this point.

@michaelfaith
Copy link
Author

Removing that mock didn't make a difference.

@michaelfaith
Copy link
Author

I found a stackoverflow post with someone seemingly having the exact same issue: https://stackoverflow.com/questions/69328284/jest-rtl-failure-mui-v5-emotion-theme-issue I've encouraged them to post a reproduction here, if they have one. I've been struggling to recreate it outside of our project. I didn't think to mention before, we're working in a yarn (1.x) workspaces environment, in case that is helpful at all.

@siriwatknp
Copy link
Member

I found a stackoverflow post with someone seemingly having the exact same issue: https://stackoverflow.com/questions/69328284/jest-rtl-failure-mui-v5-emotion-theme-issue I've encouraged them to post a reproduction here, if they have one. I've been struggling to recreate it outside of our project. I didn't think to mention before, we're working in a yarn (1.x) workspaces environment, in case that is helpful at all.

will try to reproduce it this week. will post an update on this issue.

@shaneajeffery
Copy link

shaneajeffery commented Dec 15, 2021

@siriwatknp I am the individual that posted the SO post that @michaelfaith is referencing. I too posted an issue here, but it got closed for not having a code sandbox. Unfortunately, there is something within our corporate projects that is to blame it looks like. I can get the ThemeProvider to work and inject the theme just fine if I just do a very basic example in a code sandbox.

@michaelfaith
Copy link
Author

michaelfaith commented Dec 15, 2021

@siriwatknp @shaneajeffery we were finally able to get this working. And it's not entirely clear how. I tried incrementally reducing the packages from our project to isolate the dependencies. It started working at some point, and so I started slowly adding dependencies back, and it never stopped working. So at the end of that exercise we ended up with the same package.json, but an updated yarn.lock with newer versions of a number of the packages. Some notable ones:

@emotion/styled 10.0.27 -> 10.3.0
@emotion/styled-base 10.0.31 -> 10.3.0
@emotion/jest 11.6.0 -> 11.7.1
jest & @jest/core 27.4.3 -> 27.4.5

@testing-library/react remained unchanged at 12.1.2

@shaneajeffery
Copy link

@siriwatknp @michaelfaith It is most certainly a dependency issue. I went ahead and just updated all of my dependencies in my package.json to the latest using https://www.npmjs.org/package/npm-check-updates and

npx npm-check-updates -u
npm install

Now, my issue is gone and I don't need to use the useTheme anymore to inject the theme into the styled component.

The issue has to be the older version of Emotion + MUI + Jest not playing well together. If someone else runs into this issue, I would ensure that you are on the latest version of all of the libraries and seeing where that gets you. I wish I had more of a clear-cut answer, but this issue is really just a trial-and-error bit due to the sheer volume of dependencies in the tree.

@siriwatknp
Copy link
Member

siriwatknp commented Dec 16, 2021

@michaelfaith @shaneajeffery Thanks for the info, it will save a lot of time for other people!

Note @emotion/styled & @emotion/react should be >= 11 for MUI v5

@michaelfaith
Copy link
Author

michaelfaith commented Dec 16, 2021

Note @emotion/styled & @emotion/react should be >= 11 for MUI v5

@siriwatknp Yeah, that's a good point. We have this declared in our package.json.

"@emotion/react": "^11.7.0",
"@emotion/styled": "^11.6.0",

It looks like storybook is pulling in the older emotion in addition to what we're pulling in. I wonder if this was contributing to the behavior we were experiencing.

"@storybook/theming@6.4.9":
  version "6.4.9"
  dependencies:
    "@emotion/core" "^10.1.1"
    "@emotion/is-prop-valid" "^0.8.6"
    "@emotion/styled" "^10.0.27"
    "@storybook/client-logger" "6.4.9"
    core-js "^3.8.2"
    deep-object-diff "^1.1.0"
    emotion-theming "^10.0.27"
    global "^4.4.0"
    memoizerific "^1.11.3"
    polished "^4.0.5"
    resolve-from "^5.0.0"
    ts-dedent "^2.0.0"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: waiting for author Issue with insufficient information
Projects
None yet
Development

No branches or pull requests

4 participants