emotion-js/emotion

css property does not get passed `theme` in Vitest tests

cdan-youdo opened this issue · 5 comments

Current behavior:

When rendering a component from inside a test, the theme is not passed to the css property if using ThemeProvider from @mui/material/styles. However, the test passes if ThemeProvider is imported from @emotion/react.

The component that is being tested

const StyledDiv = () => {
  return (
    <div css={
      theme => ({
        border: `6px solid ${theme.palette.secondary.main}`
      })
    } data-testid="styled-div">
    </div>
  )
}

The test

import React from 'react'
import {render, screen} from '@testing-library/react'
import { describe, expect, it } from 'vitest'

// It fails with ThemeProvider from @mui/material/styles
import { ThemeProvider } from '@mui/material/styles'
// It passes with ThemeProvider from @emotion/react
// import { ThemeProvider } from '@emotion/react'

import { default as StyledDiv } from './StyledDiv'
import { theme } from '../styles/theme'

describe('StyledDiv', () => {
  it('resolves the provided Theme', () => {
    render(
      <ThemeProvider theme={theme}>
        <StyledDiv/>
      </ThemeProvider>
    )
    const myComponent = screen.queryByTestId('styled-div');
    expect(myComponent).not.toBeNull();
    expect(myComponent).toHaveStyle({border: `6px solid ${theme.palette.secondary.main}`})
  })
})

My application root component uses the ThemeProvider from mui and works as expected when it renders in development.

import { ThemeProvider } from '@mui/material/styles';
import { theme } from 'styles/theme'
import { StyledDiv } from 'components';

export const AppContainer = () =>
  <ThemeProvider theme={theme}>
    <StyledDiv/>
  </ThemeProvider>

To reproduce:

I have put up a minimal git repo that you can use to reproduce the issue.
https://github.com/cdan-youdo/react_vitest_emotion
Once checked out, just run

yarn install
yarn vitest StyledDiv.test.tsx

Expected behavior:

I am expecting the test to pass when the component is rendered inside the ThemeProvider from @mui/material/styles.

Environment information:

  • react version: 18.3.1
  • @emotion/react version: 11.13.0

However, the test passes if ThemeProvider is imported from @emotion/react.

Why is this an issue created in the Emotion's repo then?

Why is this an issue created in the Emotion's repo then?

Because I didn't know what is the best place to post this. I have no idea if this is a Vite, emotion or mui/material issue.

I forgot to mention that my application root component uses the ThemeProvider from mui and works as expected when it renders in development.

import { ThemeProvider } from '@mui/material/styles';
import { theme } from 'styles/theme'
import { StyledDiv } from 'components';

export const AppContainer = () =>
  <ThemeProvider theme={theme}>
    <StyledDiv/>
  </ThemeProvider>

I was hoping for someone to shed some light on how the mui ThemeProvider and emotion integrate their context. This way maybe I get a better understanding and can figure out where to look for the culprit myself.

We have this problem too and this happened after the dependency @emotion/react was updated from 11.12.0 to 11.13.0.
Therefore we assumed that this might could be related with the emotion package

It seems like Vitest is not using a unified module resolution environment. Sometimes packages are resolved with one set of conditions and sometimes they are resolved with another set of conditions. This indicates a bug in Vitest

🪙 I had kinda similar resolution issue.
In-app styles worked properly, but the theme couldn't be recognized within the imported package. That was caused by the @emotion/react chunks duplication I resolved by bumping the Vite version - #3267 (comment).