Search code examples
reactjsmaterial-uienzyme

Configure Enzyme Test with material UI Theme Provider


Hi everyone I have a problem current I use material ui in my app with react, but I need to wrap each component with ThemeProvider in test to get theme throught props

 const wrapperFilter = mount(
    <MuiThemeProvider theme={createTheme(defaultTheme)}>
      <StylesProvider generateClassName={createGenerateClassName()}>
        <ThemeProvider theme={defaultTheme}>
          <SortFilter {...props} />
        </ThemeProvider>
      </StylesProvider>
    </MuiThemeProvider>
  );

but I think that is not the correct way, I tried to inject via setupTest.js but I only have option to set default theme

import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import { ThemeConsumer } from "styled-components";
import { defaultTheme } from './@next/globalStyles';


// set default theme for enzyme renderer
ThemeConsumer._currentValue = defaultTheme;
configure({ adapter: new Adapter() });

Any ideas?


Solution

  • I'm using React 18, MUI v5 and enzyme for my tests. I encountered the same issue, what I have done is:

    1. Create a file that will wrap my component in my tests injecting the theme and using shallow from enzyme:
    // enzymeThemeWrapper.js
    
    import React from 'react';
    import { ThemeProvider, StyledEngineProvider } from '@mui/material/styles';
    import theme from 'resources/myTheme';
    
    import { shallow } from 'enzyme';
    
    export const shallowMUITheme = component =>
      shallow(
        <StyledEngineProvider injectFirst>
          <ThemeProvider theme={theme}>{component}</ThemeProvider>
        </StyledEngineProvider>,
      );
    
    
    1. then use it like so in my tests:
    import React from 'react';
    import { shallowMUITheme } from 'utils/enzymeThemeWrapper';
    import Screen from '../screen';
    
    describe('screen', () => {
      it('should render screen', () => {
        const component = shallowMUITheme(
          <Screen />,
        );
    
        expect(component).toMatchSnapshot();
      });
    });
    

    You probably figured this out since then, I would be curious to know what solution you came up with to solve your issue.