javascript - 在测试库中测试 css-modules 样式

标签 javascript reactjs jestjs react-testing-library react-css-modules

React Context 提供程序从 module.scss 文件导入样式类。 执行此组件时,将加载选定的样式类并将其作为 className 传递给子组件。

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>
  )
}

如果调用 changeTheme,以下输出将记录到控制台。

{
    "dark": "x05Ym2JQjxImZ4atKmpS",
    "light": "hOdKKkIeHEdunEiPWlEL"
}

changing Theme
x05Ym2JQjxImZ4atKmpS

当尝试使用自定义渲染器使用 testing-library 来测试此组件时

/**
 * 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>
  )
}

以及以下测试

  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)
  })

执行测试时,来自自定义渲染器的 CLICK! 消息将记录为与在浏览器中执行时相同的 console.log 语句。只是,在需要 CSS 样式类的地方,我得到一个空对象。

{}

changing Theme
dark

使用的 Jest 配置是

/**
 * @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
    }
  }
}

是否有配置、模块或任何其他更改能够解析 Jest 中的 css 模块,就像通过 Webpack 服务 在本地托管它一样?

最佳答案

使用以下两个 jest 转换配置替换 jest-css-modules moduleNameMapper 解决了该问题。

yarn add --dev babel-jest jest-css-modules-transform

和 Jest 配置

  transform: {
    '^.+\\.[jt]sx?$': 'babel-jest',
    '.+\\.(css|styl|less|sass|scss)$': 'jest-css-modules-transform'
  },

关于javascript - 在测试库中测试 css-modules 样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71881494/

相关文章:

javascript - Firebase存储规则错误: unexpected identifier; function taken from documentation

javascript - 处理从 props 传递的数据排序的最佳方法是什么?

javascript - react-pdf-js - 未捕获( promise )e {name : "InvalidPDFException", message: "Invalid PDF structure"}

reactjs - React&Searchkit显示更多按钮,而不是默认分页

javascript - 开 Jest mock 类(class)强制不同的 react , typescript

javascript - 顶部菜单显示一个空白选项,将我重定向到一个未定义的页面。我该如何解决?

javascript - 或者 JavaScript 中的声明?

javascript - NodeJS 更新 API - 内部服务器错误

javascript - 即使在错误之后继续检查expect()也是开 Jest

jestjs - 意外的 token '<' 开 Jest 和测试库/ react 原生与 typescript 测试文件