React + Jest - 测试 IMG 标签上的 `error` 事件

3

有没有办法触发标签的error事件,以测试我的onError回调函数?例如,给定这个组件,

import React from 'react';

/**
 * Self removing <img> when the `src` or image
 * does not load or is unavailable.
 *
 * Usage: (tip: it's how you use the <img> tag, basically)
 * <Img src={} alt={} ../..>
 */
var Img = React.createClass({
  /**
   * Force update so `refs` will be available
   */
  componentDidMount() {
    this.forceUpdate();
  },

  render() {
    // Omit any passed `onError` prop so that
    // it is never overridden by mistake
    var { onError, ...other } = this.props;

    return (
      <span ref="container">
        <img {...other} onError={this._handleError} />
      </span>
    )
  },

  /**
   * Remove itself when image is not found
   */
  _handleError() {
    this.refs.container.getDOMNode().remove();
  }
});

export default Img;

以及这个测试套件:

it('should remove itself when an error occurs while loading the image', function() {
  // rendered = TestUtils.renderIntoDocument(<Img />);
});
2个回答

7
我发现 React 的测试工具(React.addons.TestUtils)非常有帮助,提供了像 SimulateReact.addons.TestUtils.Simulate)这样的实用程序。在这种情况下,Simulate 将起到作用。
来自 React 文档 上的 测试工具

模拟 DOM 节点上的事件分发,可选的 eventData 事件数据。这可能是 ReactTestUtils 中最有用的实用程序。

it('should remove itself when an error occurs while loading the image', function() {
  var rendered = TestUtils.renderIntoDocument(<Img />);
  var img = TestUtils.findRenderedDOMComponentWithTag(rendered, 'img');
  TestUtils.Simulate.error(img);

  // In this case, we can try to find (again) the tag.
  // `TestUtils.findRenderedDOMComponentWithTag` throws an error
  // when the provided tag cannot be found.
 expect(function() {
   TestUtils.findRenderedDOMComponentWithTag(rendered, 'img');
 }).toThrow();
});

以下内容可能与主题无关。使用 state 可以改进示例组件。
import React from 'react';

/**
 * Self removing <img> when the `src` or image
 * does not load or is unavailable.
 *
 * Usage: (tip: it's how you use the <img> tag, basically)
 * <Img src={} alt={} ../..>
 */
var Img = React.createClass({
  // We'll set `error` to false to load and display the image,
  // only will it be true when an error occurs
  getInitialState() { 
    return { error: false }
  },

  render() {
    // Omit any passed `onError` prop so that
    // it is never overridden by mistake
    var { onError, ...other } = this.props;

    return !this.state.error ? (
      <span>
        <img {...other} onError={this._handleError} />
      </span>
    ) : null;
  },

  /**
   * Set `state` error to true to remove the
   * the dom nodes themselves
   */
  _handleError() {
    this.setState({ error: true });
  }
});

export default Img;

然后使用以下测试套件:

it('should remove itself when an the image loads with an error', function() {
  var rendered = TestUtils.renderIntoDocument(<Img />);
  var img = TestUtils.findRenderedDOMComponentWithTag(rendered, 'img');
  TestUtils.Simulate.error(img);

  // When no results come out of `findRenderedDOMComponentWithTag`,
  // it throws an error 'Did not find exactly one match for tag:img'
  expect(function() {
    TestUtils.findRenderedDOMComponentWithTag(rendered, 'img')
  }).toThrow('Did not find exactly one match for tag:img');
  expect(rendered.state.error).toBe(true);
});

2
使用jest和react测试库非常容易。
在实际代码中,我们正在监听onError事件。
const handleImgError = (e) => {
  e.target.src = 'https://default-placehodler-image-path.svg';
};

<img
  src='http://4040.jpg'
  onError={handleImgError}
/>


在测试代码中
import { render, waitFor, fireEvent } from '@testing-library/react';

const { container } = render(<TestComponent />);

// get img element
const imgEl = container.querySelector('img');

// simulate error event on element
fireEvent.error(imgEl, {
  target: imgEl,
});

// expect updated change on img element
await waitFor(() => {
  expect(imgEl.src).toEqual(
    'https://default-placehodler-image-path.svg'
  );
});


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接