reactjs - 如何使用 enzyme 对 Material-ui 文本字段进行单元测试?

标签 reactjs material-ui enzyme

我仍在使用 Enzyme 和 Material-ui 学习 ReactJS。

我有一个带有 Material-ui 的 TextField 的组件,我想对以下情况进行单元测试。

  1. 当用户在屏幕上的 TextField 上输入字符串“123”时,TextField 应将“error”设置为“true”并显示消息“名称格式错误”。

组件

import React, { useState } from "react";
import TextField from "@material-ui/core/TextField";
import Grid from "@material-ui/core/Grid";

export const NameTextField = props => {
  const { onStateChange } = props;
  const [state, setState] = useState({
    errors: [],
    onChange: false,
    pristine: false,
    touched: false,
    inProgress: false,
    value: {
      name: ""
    }
  });
  const handleOnBlur = async event => {
    const inputStringLC = String(event.target.value).toLowerCase();

    // First verify the email is in good format
    if (inputStringLC !== "123") {
      // If true, verify username is available
      const updatedState = {
        ...state,
        touched: true,
        pristine: true,
        value: {
          name: inputStringLC
        },
        inProgress: false,
        errors: []
      };
      setState(updatedState);
      onStateChange(updatedState);
    } else {
      const updatedState = {
        ...state,
        touched: true,
        pristine: false,
        value: {
          name: inputStringLC
        },
        errors: ["Wrong Name format."]
      };
      setState(updatedState);
      onStateChange(updatedState);
    }
  };

  return (
    <Grid container spacing={1}>
      <Grid item xs={12}>
        <TextField
          variant="outlined"
          required
          fullWidth
          id="name"
          label="Name"
          error={state.errors.length > 0}
          helperText={state.errors.length > 0 ? state.errors[0] : null}
          name="name"
          autoComplete="name"
          margin="dense"
          onBlur={handleOnBlur}
        />
      </Grid>
    </Grid>
  );
};

export default NameTextField;

单元测试

import React from 'react';
import { configure, shallow, mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import NameTextField from './NameTextField';
import TextField from '@material-ui/core/TextField';
import { createShallow } from '@material-ui/core/test-utils';


configure({adapter: new Adapter()});

describe('<NameTextField />', ()=> {
  let shallow;

  beforeAll(() => {
    shallow = createShallow();
  });
  let wrapper;
  beforeEach(()=>{
    wrapper =  shallow(<NameTextField />);
  });

  it('should render one <TextField /> element.', ()=>{
    expect(wrapper.find(TextField)).toHaveLength(1);
  });


  it('should show error when entered', ()=>{
    wrapper.find('#name').simulate('change', {target: {value: '123'}});
    expect(wrapper.find("#name").props().error).toBe(
        true);
    expect(wrapper.find("#name").props().helperText).toBe(
        'Wrong Name format.');
  });


});

我收到以下错误。 错误:expect(received).toBe(expected)//Object.is 相等

预期:正确 收到:假

我在这里做错了什么吗?

最佳答案

我用这个解决了这个问题。为有相同情况的人发布解决方案。

  1. 我尝试使用 mount,但它变得非常复杂,因为 Material-ui 有很多嵌套样式组件 init。所以我改用了shallow。
import React from 'react';
import {configure} from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import NameTextField from './NameTextField';
import TextField from '@material-ui/core/TextField';
import {createShallow} from '@material-ui/core/test-utils';
import {act} from 'react-dom/test-utils';

configure({adapter: new Adapter()});

describe('<NameTextField />', () => {
  let shallow;

  beforeAll(() => {
    shallow = createShallow();
  });
  let wrapper;
  beforeEach(() => {
    wrapper = shallow(<NameTextField onStateChange={handleStateChange}/>);
  });

  const handleStateChange = updatedState => {
  };

  it('should show no error when first entered', () => {
    expect(wrapper.find(TextField).at(0).props().error).toBe(
        false);
    expect(wrapper.find(TextField).at(0).props().helperText).toBe(
        null);
  });

  it('should show error when nothing entered', () => {
    act(() => {
      wrapper.find(TextField).at(0).simulate('blur', {target: {value: '123'}});
    });
    wrapper.update();
    expect(wrapper.find(TextField).at(0).props().error).toBe(
        true);
    expect(wrapper.find(TextField).at(0).props().helperText).toBe(
        "Wrong Name format.");
  });

  it('should show no error when correctly entered', () => {
    act(() => {
      wrapper.find(TextField).at(0).simulate('blur', {target: {value: 'James'}});
    });
    wrapper.update();
    expect(wrapper.find(TextField).at(0).props().error).toBe(
        false);
    expect(wrapper.find(TextField).at(0).props().helperText).toBe(
        null);
  });

});

希望这有帮助。感谢所有在这方面帮助过我的人。

关于reactjs - 如何使用 enzyme 对 Material-ui 文本字段进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57162445/

相关文章:

javascript - 设置函数在测试自定义 Hook usePrevious 时返回未定义

javascript - Firebase 实时数据库 - "Error: Client is offline"。 react /NextJS

reactjs - 如何将 validate-state 与 React-bootstrap 一起使用

javascript - 如何处理更改 TextInput 组件?

javascript - 导入 es6 模块的最佳方法是什么?

javascript - Material-UI List 作为 Card 的子项,在主展开时触发所有 onClick

javascript - 如何使用 react enzyme 检查实际的 DOM 节点

reactjs - 测试 React 事件处理程序

reactjs - React 仅针对有省略号的文本显示 Material-UI 工具提示

css - 如何在嵌套网格中对齐元素(React Material UI)