【问题标题】:ReactWrapper can only wrap valid elements (material-ui - enzyme)ReactWrapper 只能包装有效元素(material-ui - 酶)
【发布时间】:2020-12-31 09:15:51
【问题描述】:

我正在为组件编写测试以测试其功能之一,但出现错误:ShallowWrapper 只能包装有效元素

组件文件如下-TextInput.js:

  /* eslint-disable react/require-default-props */
import React from 'react'
import PropTypes from 'prop-types'
import { InputLabel, TextField } from '@material-ui/core'

const TextInput = ({
  name, label, onChange, placeholder, value, error, optional = false, isDisable = false, t,
}) => (
  <>
    {label ? (
      <InputLabel htmlFor={name} className="default-style_label">
        {label}
        {' '}
        {optional && <span className="optional">{`(${t('application.optional')})`}</span>}
      </InputLabel>
    ) : ''}
    <TextField
      type="text"
      name={name}
      placeholder={placeholder}
      value={value}
      // isRequired={isRequired}
      disabled={isDisable}
      onChange={onChange}
      error={error && true}
      helperText={error}
      variant="outlined"
      className="default-style_input"
    />
  </>
)

TextInput.propTypes = {
  name: PropTypes.string.isRequired,
  label: PropTypes.string,
  onChange: PropTypes.func.isRequired,
  placeholder: PropTypes.string,
  value: PropTypes.string,
  error: PropTypes.string,
  optional: PropTypes.bool,
  isDisable: PropTypes.bool,
  t: PropTypes.func,
}

export default TextInput

测试文件

   /* eslint-disable no-undef */
import React from 'react'
import { shallow, mount } from 'enzyme'
import TextInput from '../TextInput'

function createTestProps(props) {
  return {
    // common props
    name: 'test',
    label: 'foo',
    value: 'bar',
    onChange: jest.fn(),
    // allow to override common props
    ...props,
  }
}

describe('rendering', () => {
  describe('<TextInput>', () => {
    let wrapper
    let instance
    beforeEach(() => {
      const props = createTestProps()
      wrapper = mount(shallow(<TextInput {...props} />)).get(0)
      instance = wrapper.instance()
    })

    afterEach(() => {
      jest.clearAllMocks()
    })

    it('should be rendered', () => {
      const content = wrapper.find('input').at(1)
      console.debug(content.debug())
      console.log(instance)
      expect(content.value).toBe('bar')
    })
  })
})

问题是我的测试在删除挂载时失败

wrapper = mount(shallow()).get(0)

与一个比较值没有视觉差异 任何想法为什么会发生这种情况将不胜感激!

【问题讨论】:

    标签: reactjs jestjs material-ui enzyme


    【解决方案1】:

    使用@material-ui 时会有所不同。

    您必须使用 @material-ui 的内置 API。如createMount、createShallow、createRender为了利用酵素的shallow、mount & render。

    这些 API 是基于酶构建的,因此您不能直接使用酶来测试 @material-ui。

    这是我的测试文件

       /* eslint-disable no-undef */
    import React from 'react'
    import { createMount } from '@material-ui/core/test-utils'
    import TextField from '@material-ui/core/TextField'
    import TextInput from '../TextInput'
    
    function createTestProps(props) {
      return {
        // common props
        name: 'test',
        label: 'foo',
        value: 'bar',
        onChange: jest.fn(),
        // allow to override common props
        ...props,
      }
    }
    
    describe('rendering', () => {
      describe('<TextInput>', () => {
        let mount
        let props
        beforeEach(() => {
          mount = createMount()
          props = createTestProps()
        })
    
        afterEach(() => {
          mount.cleanUp()
        })
    
        it('renders a <TextField/> component with expected props', () => {
          const wrapper = mount(<TextInput {...props} />)
          expect(wrapper.props().name).toEqual('test')
          expect(wrapper.props().onChange).toBeDefined()
        })
    
        it('should trigger onChange on <TextField/> on key press', () => {
          const wrapper = mount(<TextInput {...props} />)
          wrapper.find('input').simulate('change')
          expect(props.onChange).toHaveBeenCalled()
        })
      })
    })
    

    我在这里找到了解决方案 Material UI + Enzyme testing component

    【讨论】:

      【解决方案2】:

      您应该根据您的用例使用 mount 或 shallow 来渲染您的组件。

      • 如果你想渲染你的组件,所有子节点都将被渲染到最后一个叶节点,请使用 mount。

      • 如果您需要对组件进行深度渲染,请使用浅层。

      注意:在大多数情况下,您应该使用浅渲染,因为挂载需要很长时间。

      【讨论】:

        【解决方案3】:

        你应该使用 shallow 或 mount,而不是两者都使用。

        wrapper = mount(<TextInput {...props} />);
        
        const content = wrapper.find('input');
        expect(content.value).toBe('bar');
        

        【讨论】:

          猜你喜欢
          • 2020-03-10
          • 2019-05-02
          • 1970-01-01
          • 2020-12-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-02-10
          • 1970-01-01
          相关资源
          最近更新 更多