Reputation: 977
A React Context provider imports style classes from a module.scss
file.
When executing this component a selected style class is loaded and passed as the className
to child components.
import React, {createContext, ReactChild, useState} from 'react'
import themes from './ThemeProvider.module.scss'
type ThemeContext = {
activeTheme: string
changeTheme: (theme: string) => void
}
const validThemes = Object.keys(themes)
console.log(themes)
const defaultTheme = 'light'
const defaultThemeContext: ThemeContext = {
activeTheme: defaultTheme,
changeTheme: () => undefined
}
type ThemeProviderProps = {
children: ReactChild
}
export const ThemeContext = createContext<ThemeContext>(defaultThemeContext)
export const ThemeProvider = ({children}: ThemeProviderProps): JSX.Element => {
const [theme, setTheme] = useState(defaultThemeContext.activeTheme)
const changeTheme = (themeName: string): void => {
console.log('changing theme')
console.log(themes[themeName])
if (validThemes.includes(themeName)) {
setTheme(themeName)
} else {
setTheme(defaultTheme)
}
}
const themeContext = {
activeTheme: theme,
changeTheme: changeTheme
}
return (
<ThemeContext.Provider value={themeContext}>
<div className={themes[theme]} data-testid='theme-provider'>
{children}
</div>
</ThemeContext.Provider>
)
}
If changeTheme
is invoked the following output is logged to the console.
{
"dark": "x05Ym2JQjxImZ4atKmpS",
"light": "hOdKKkIeHEdunEiPWlEL"
}
changing Theme
x05Ym2JQjxImZ4atKmpS
When trying to test this component in using testing-library
using a custom renderer
/**
* Custom renderer
*/
const ThemeConsumer = (): JSX.Element => {
const {changeTheme, activeTheme} = useContext(ThemeContext)
return (
<div>
<button
data-testid='theme-consumer-btn'
onClick={() => {
console.log('CLICK!')
changeTheme('dark')
}}
/>
<p>Theme:{activeTheme} </p>
</div>
)
}
And the following test
test('changes theme', async () => {
render(
<ThemeProvider>
<ThemeConsumer />
</ThemeProvider>
)
const consumerBtn = (await screen.findByTestId(
'theme-consumer-btn'
)) as HTMLButtonElement
await userEvent.click(consumerBtn)
await waitFor(() => screen.getByText('Theme:dark'))
screen.debug(undefined, Infinity)
})
On execution of the test the CLICK!
message from the custom renderer is logged as the same console.log
statements when executed in a browser. Only, where the CSS style classes were expected i get an empty object.
{}
changing Theme
dark
Used Jest config is
/**
* @jest-environment jsdom
*/
module.exports = {
collectCoverageFrom: ['src/**/*.ts', 'src/**/*.tsx', '!src/**/*.test.*'],
moduleNameMapper: {
'\\.(scss)$': '<rootDir>/node_modules/jest-css-modules'
},
testEnvironment: 'jsdom',
globals: {
PRODUCTION: true
},
testMatch: ['**/?(*.)test.[tj]sx'],
testURL: 'https://www.mijnmarkt.nl',
coverageThreshold: {
global: {
lines: 100,
statements: 100
}
}
}
Is there a configuration, module or any other change to be able to parse css-modules in Jest as when hosting it locally through a Webpack serve
?
Upvotes: 2
Views: 5786
Reputation: 977
replacing the jest-css-modules
moduleNameMapper with the following two jest transform configurations fixed the issue.
yarn add --dev babel-jest jest-css-modules-transform
and jest config
transform: {
'^.+\\.[jt]sx?$': 'babel-jest',
'.+\\.(css|styl|less|sass|scss)$': 'jest-css-modules-transform'
},
Upvotes: 3