ReactJS Ant设计选择组件模拟更改事件

时间:2018-05-28 12:25:37

标签: reactjs unit-testing jestjs enzyme antd

组件MyComp包含Select Ant component并愿意测试MyComp以确保处理程序正确并被调用

cat webpack.development.js
const path = require('path');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const StatusPlugin = require('./front/utils/webpack-status-plugin');
const HappyPack = require('happypack');

const paths = {
  src: path.join(__dirname, 'front'),
  dest: path.join(__dirname, 'public', 'front'),
};

module.exports = {
  context: paths.src,
  devtool: 'eval',
  entry: {
    application: ['babel-polyfill', './application.js'],
    admin: ['babel-polyfill', './admin.js'],
    portal: ['babel-polyfill', './portal.js'],
  },
  externals: {
    jquery: 'jQuery',
    underscore: '_',
  },
  output: {
    path: paths.dest,
    filename: '[name].bundle.js',
    sourceMapFilename: '[name].js.map',
  },
  module: {
    loaders: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        loader: 'happypack/loader',
      },
      {
        parser: {
          amd: false,
        },
      },
    ],
  },
  plugins: [
    new CleanWebpackPlugin(paths.dest),
    new HappyPack({
      loaders: ['babel-loader'],
      verbose: false,
    }),
    StatusPlugin,
  ],
  resolve: {
    modules: [paths.src, 'node_modules'],
  },
  watch: true,
  watchOptions: {
    ignored: /node_modules/,
  },
};

我希望能够按如下方式测试它:

class MyComp extends Component {
    constructor(props) {
        super(props);
        this.handleChange = this.handleChange.bind(this);
    }

    handleChange(value) {
        this.props.doSomething();
    }

    render() {
        return (
            <Select onChange={this.props.handleChange}>
                <Option value={"Op0"} >Opt0</Option>
                <Option value={"Op1"} >Opt1</Option>
                <Option value={"Op2"} >Opt2</Option>
            </Select>
        )
    }
}

请记住它的'mount'不浅,所以它实际上是渲染子组件

2 个答案:

答案 0 :(得分:0)

作为一种方法,您可以使用

select.prop('onChange')()

代替select.simulate


另外,您可以打开antd选择菜单,检查值并继续进行测试(取决于所使用的antd版本)。

在antd V3中,您可以使用简单的fireEvent.click

// Opens the Drop down
fireEvent.click(getByText("Value 1"));

但是使用antd V4,您需要使用mouseDown通话

const elt = getByTestId('your-select-test-id').firstElementChild;
fireEvent.mouseDown(elt); // THIS WILL OPEN THE SELECT !
expect(getByText('Option from Select')).toBeInTheDocument(); // WORKS !

请参阅github issue

答案 1 :(得分:0)

有点晚了,但是摆脱与Jest与Ant Design Selects交互的所有麻烦的另一种解决方案是通过将this kind of mock放在Jest设置文件(或仅限特定的测试套件)。这样,所有的Select都将被旧的本机选择替换,这些选择在单元测试环境中更加友好。

将单元测试与可能会更改(或完全删除...)的UI库分离也是一件好事,它也可以使您的测试更快(Ant Design Selects等UI组件可能很复杂)。

使用该模拟程序,您可以执行类似的操作(我使用的是react-testing-library,但我想应该可以与酶一起使用):

// Assuming a <Select data-testid="mySelect">...</Select> in component tested

// Update the selected option, triggering a onChange event
// No more click / mouseDown the input, find the right option in virtual list...
fireEvent.change(getByTestId('mySelect'), { target; { value: 'optionValue' } });

const options = getByTestId('mySelect').querySelectorAll('option');
expect(options[0].textContent).toEqual('first option text');
expect(options[0]).toHaveValue('option1Value');

// or test all in one shot
expect(Array.from(options).map(o => o.getAttribute('value'))).toEqual(['value1', 'value2']);

到目前为止,这确实比与真正的Selects交互更方便。