【问题标题】:How do I mock the implementation of material-ui withStyles?如何模拟 Material-ui withStyles 的实现?
【发布时间】:2023-03-07 09:15:01
【问题描述】:

如何在material-ui/core/styles.js 中模拟withStyles 的实现?

这是测试:

import React from 'react'
import { shallow } from 'enzyme'
import { withStyles } from '@material-ui/core/styles'

import TempComponent from './TempComponent'

jest.mock('@material-ui/core')

it('renders correctly', () => {
  const withStylesFake = styles =>
    component => (
      component
    )

  withStyles.mockImplementation(withStylesFake)

  const wrapper = shallow(<TempComponent />)
  expect(wrapper).toMatchSnapshot()
})

代码如下:

import React from 'react'
import { withStyles } from '@material-ui/core/styles'

const TempComponent = () => (
  <button>Click Me!</button>
)

export default withStyles({})(TempComponent)

这是错误:

TypeError: _styles.withStyles.mockImplementation is not a function

  at Object.<anonymous>.it (src/TempComponent.snapshot.test.js:15:22)
      at new Promise (<anonymous>)
  at Promise.resolve.then.el (node_modules/p-map/index.js:46:16)
      at <anonymous>
  at process._tickCallback (internal/process/next_tick.js:188:7)

这可行:

// ./__mocks__/@material-ui/core/styles
export const withStyles = styles => (
  component => (
    component
  )
) 

但这不是测试本地的。

【问题讨论】:

    标签: reactjs mocking jestjs material-ui


    【解决方案1】:

    我发现的方法是按如下方式导出组件。无需模拟。

    测试:

    import React from 'react'
    import { shallow } from 'enzyme'
    
    import { TempComponent } from './TempComponent'
    
    it('renders correctly', () => {
      const wrapper = shallow(<TempComponent />)
      expect(wrapper).toMatchSnapshot()
    })
    

    实施:

    import React from 'react'
    import { withStyles } from '@material-ui/core/styles'
    
    export const TempComponent = () => (
      <button>Click Me!</button>
    )
    
    export default withStyles({})(TempComponent)
    

    【讨论】:

      【解决方案2】:

      因为TempComponent 导入是在您的测试代码之前评估的,所以您需要在此过程的早期模拟 withStyles。在过程中调用 mockImplementation 为时已晚。

      有两种方法可以做到这一点:将工厂传递给jest.mock,或使用手动模拟。手动模拟对您有用,但您说您想要测试本地的东西,所以您需要使用工厂参数。方法如下。

      模拟 styles 导入而不是 core 导入。使用 jest.mock 的第二个参数,“模块工厂参数”,传入模块工厂函数:一个返回替换 styles 导入的对象的函数。出于您的目的,这意味着该对象需要具有 withStyles 函数:

      jest.mock('@material-ui/core/styles', () => ({
        withStyles: styles => component => component
      }));
      

      无需将withStyles 导入您的测试或调用mockImplementation;您可以删除这些行。

      【讨论】:

      • 嘿,不错。但是,如何做到这一点并模拟作为参数传递给withStylestheme 对象?
      • @GuilhermeVasconcelos,我可能不明白你想做什么,但如果你的目标是测试包装在 withStyles 中的组件,而不是测试 withStyles 本身(是由其他人编写的),那么您不需要模拟主题对象。要测试将由 withStyles 包装器设置的不同值,请将它们设置为测试中组件上的道具。如果这没有帮助,最好提出一个新问题。
      • 实际上,我正在测试一个我命名为 export 的组件,以避免它自己的 withStyles。但是,它在内部使用另一个组件,该组件也有一个 withStyles style = (theme) =&gt; ...theme.pallete 等。所以代码中断,因为我正在设置一个主题(并且不想)。
      • 最好发布一个新问题。
      • @GuilhermeVasconcelos 从今天早上开始我就一直在寻找这个,我找到了一种模拟makeStyles 并使其使用自定义主题而不是默认主题的方法。但不是我没有真正使用的withStyles,我留在 Hook 练习中。我只是模拟,并将函数作为参数传递给bind.(null, theme),在那里我用玩笑在手动模拟全局级别创建主题。
      【解决方案3】:

      这是我用 Material UI 定义组件样式的一种方式。

      import { withStyles } from '@material-ui/core/styles';
      
      const styles = theme => ({
        root: {
          ...theme.mixins.gutters(),
          paddingTop: theme.spacing.unit * 2,
          paddingBottom: theme.spacing.unit * 2,
          marginBottom: theme.spacing.unit * 3,
          maxWidth: theme.spacing.unit * 120,
          overflowX: 'auto',
        },
      });
      
      function PaperSheet() {
          return (
              <Paper className={classes.root} elevation={1} />
          );
      }
      
      export default withStyles(styles)(PaperSheet);
      

      【讨论】:

      • 问题是关于模拟withStyles 进行测试。您的答案看起来不像是针对测试或模拟的。
      猜你喜欢
      • 2020-06-24
      • 2019-07-12
      • 1970-01-01
      • 2020-06-21
      • 1970-01-01
      • 1970-01-01
      • 2019-10-11
      • 2019-11-21
      • 2018-11-20
      相关资源
      最近更新 更多