如何模拟Material-ui withStyles的实现?

Dev*_*avo 2 mocking reactjs jestjs material-ui

如何模拟withStylesin 的实现material-ui/core/styles.js

这是测试:

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()
})
Run Code Online (Sandbox Code Playgroud)

这是代码:

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

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

export default withStyles({})(TempComponent)
Run Code Online (Sandbox Code Playgroud)

这是错误:

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)
Run Code Online (Sandbox Code Playgroud)

这将工作:

// ./__mocks__/@material-ui/core/styles
export const withStyles = styles => (
  component => (
    component
  )
) 
Run Code Online (Sandbox Code Playgroud)

但这不是测试的局部内容。

Dev*_*avo 5

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

测试:

import React from 'react'
import { shallow } from 'enzyme'

import { TempComponent } from './TempComponent'

it('renders correctly', () => {
  const wrapper = shallow(<TempComponent />)
  expect(wrapper).toMatchSnapshot()
})
Run Code Online (Sandbox Code Playgroud)

实现方式:

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

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

export default withStyles({})(TempComponent)
Run Code Online (Sandbox Code Playgroud)


sto*_*one 5

由于TempComponent导入是在测试代码之前进行评估的,因此您需要在此过程的早期模拟 withStyles。在过程中调用 mockImplementation 太晚了。

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

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

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

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