Reputation: 2266
In short, I'm using Jest, React Testing Library, and Material UI createMuiTheme
and everything works except for the tests. They break only when I add the custom theme from my compound theme from createMuiTheme
.
I'm creating a custom theme for my MUI project as follows:
import { createMuiTheme } from '@material-ui/core/styles';
export const theme = {
palette: {
extra: {
activeButton: '#D4564E',
black: '#000000',
darkGrey: '#232323',
rgbaInvisible: 'rgba(0, 0, 0, 0)',
success: '#4CAF50',
white: '#FFFFFF',
},
},
};
export default createMuiTheme(theme);
My component styles are defined in JSS like this:
const useStyles = makeStyles((theme) => {
return {
ctaCopy: {
color: theme.extraColors.activeButton,
},
};
});
The component itself I don't think is important but it looks like this:
<Link className={classes.ctaCopy} href={ctaUrl}>
{ctaCopy}
</Link>
This works. The component displays properly when rendered, with the expected colors. However, when I use this component in a Jest test, it fails, saying:
TypeError: Cannot read property 'activeButton' of undefined
Update:
I dug a little further and attempted a few other solutions, including using MuiThemeProvider
and ThemeProvider
(separately, of course). In order to do this, I used import
to pull in my custom theme, which is hosted in an external library. As follows:
import { defaultTheme } from 'my-external-lib';
This, again, works on a rendered page. I went so far as to console.log
the defaultTheme
and it prints correctly, again, in the rendered page. However, in the tests, if I console.log(defaultTheme)
the result is undefined!!
So perhaps the updated question nuance is, why can't I use import
in this way with Jest/React Testing Library?
This may warrant a whole new question being posted.
More of what I've tried so far:
// This theme created as above
import { ThemeProvider } from '@material-ui/core';
import { defaultTheme } from '@my-external-lib';
import MyComponent from './MyComponent';
const setupComponent = ({
ctaCopy,
ctaUrl,
} = {}) => {
render(
<ThemeProvider theme={defaultTheme}>
<MyComponent
ctaCopy={ctaCopy}
ctaUrl={ctaUrl}
/>
</ThemeProvider>,
);
};
const testCtaCopy = 'test-cta-copy';
const testCtaUrl = 'https://www.test.com';
describe('My component', () => {
it('should render', () => {
expect.assertions(1);
setupComponent({ ctaCopy: testCtaCopy, ctaUrl: testCtaUrl });
expect(screen.getByText(testCtaCopy)).toBeInTheDocument();
});
});
Why am I getting this error in tests only?
Upvotes: 10
Views: 4250
Reputation: 111
I encountered this today, the solution that fixed for me is this
const useStyles = makeStyles((theme) => {
return {
ctaCopy: {
color: theme.extraColors?.activeButton,
},
};
});
Upvotes: 2
Reputation: 62
To be honest, I'm very new to JS, React, and Jest, but I was able to fix a similar problem where I got a similar error (related to the new MUI v5 update) so here's my best guess:
Perhaps you receive errors on test and not when running src, because:
TypeError: Cannot read property 'activeButton' of undefined
, Sound's like your theme isn't being picked up and used by makestyles() properly. (although it looks like you followed the docs perfectly fine & displayed your theme, so my guess is this is an issue on the JEST side or a minor bug with MUI)
What I did to fix a similar error was move my theme into the same file as my JSS, and refer to my theme directly in makeStyles(), rather than pass theme
as a param.
So something like:
const themeAttr = {
palette: {
extra: {
activeButton: '#D4564E',
black: '#000000',
darkGrey: '#232323',
rgbaInvisible: 'rgba(0, 0, 0, 0)',
success: '#4CAF50',
white: '#FFFFFF',
},
},
};
const theme = createMuiTheme(themeAttr);
const useStyles = makeStyles( => {
return {
ctaCopy: {
color: theme.extraColors.activeButton,
},
};
});
I did not use createMUITheme
in my project. I only used createTheme()
. However this did fix the errors I was receiving during test, so I hope this helps!
Upvotes: 0