怎么用Jest测试img.onerror [英] How do you use Jest to test img.onerror

查看:36
本文介绍了怎么用Jest测试img.onerror的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个 React 组件,用于加载图像并确定图像是否成功加载.

I've created a React component that loads an image and determines if the image loaded successfully or not.

import React from 'react';
import PropTypes from 'prop-types';
import { LOADING, SUCCESS, ERROR } from '../helpers';

class Image extends React.Component {
  static propTypes = {
    onError: PropTypes.func,
    onLoad: PropTypes.func,
    src: PropTypes.string.isRequired,
  }

  static defaultProps = {
    onError: null,
    onLoad: null,
  }

  constructor(props) {
    super(props);
    this.state = { imageStatus: LOADING };
    this.initImage();
  }

  componentDidMount() {
    this.image.onload = this.handleImageLoad;
    this.image.onerror = this.handleImageError;
    this.image.src = this.props.src;
  }

  initImage() {
    this.image = document.createElement('img');
    this.handleImageLoad = this.handleImageLoad.bind(this);
    this.handleImageError = this.handleImageError.bind(this);
  }

  handleImageLoad(ev) {
    this.setState({ imageStatus: SUCCESS });
    if (this.props.onLoad) this.props.onLoad(ev);
  }

  handleImageError(ev) {
    this.setState({ imageStatus: ERROR });
    if (this.props.onError) this.props.onError(ev);
  }

  render() {
    switch (this.state.imageStatus) {
      case LOADING:
        return this.renderLoading();
      case SUCCESS:
        return this.renderSuccess();
      case ERROR:
        return this.renderError();
      default:
        throw new Error('unknown value for this.state.imageStatus');
    }
  }
}

export default Image;

我正在尝试使用 Jest + Enzyme 创建一个测试,以测试图像何时无法加载.

I'm trying to create a test using Jest + Enzyme to test when an image fails to load.

  it('should call any passed in onError after an image load error', () => {
    const onError = jest.fn();
    mount(<Image {...props} src="crap.junk"} onError={onError} />);
    expect(onError).toHaveBeenCalled();
  });

无论我做什么,Jest 总能找到一种方法来成功渲染图像.即使将 src 设置为 false 仍然以某种方式呈现图像.有谁知道你到底是如何强迫 jest 使图像加载失败的?

No matter what I do, Jest always finds a way to successfully render the image. Even setting src to false still renders an image somehow. Does anyone know how in the heck you can force jest to fail an image load?

推荐答案

由于在幕后,document.createElement('img') 等价于 new Image(),我们可以模拟 Image 的 jsdom(由 Jest 使用)实现的一部分来实现您的目标.

Since behind the scenes, document.createElement('img') is equivalent to new Image(), we can mock part of the jsdom (used by Jest) implementation of Image to achieve what you're going for.

(为简单起见,我将您的组件重命名为 ImageComponent)

(For simplicity's sake, I've renamed your component to ImageComponent)

describe('Callbacks', () => {
  const LOAD_FAILURE_SRC = 'LOAD_FAILURE_SRC';
  const LOAD_SUCCESS_SRC = 'LOAD_SUCCESS_SRC';

  beforeAll(() => {
    // Mocking Image.prototype.src to call the onload or onerror
    // callbacks depending on the src passed to it
    Object.defineProperty(global.Image.prototype, 'src', {
      // Define the property setter
      set(src) {
        if (src === LOAD_FAILURE_SRC) {
          // Call with setTimeout to simulate async loading
          setTimeout(() => this.onerror(new Error('mocked error')));
        } else if (src === LOAD_SUCCESS_SRC) {
          setTimeout(() => this.onload());
        }
      },
    });
  });

  it('Calls onError when passed bad src', done => {
    const onError = ev => {
      expect(ev).toBeInstanceOf(Error);

      // Indicate to Jest that the test has finished
      done();
    };

    mount(<ImageComponent onError={onError} src={LOAD_FAILURE_SRC} />);
  });
});

onerror/onload 从未像在浏览器中那样被调用的原因在此 jsdom 问题.在同一个问题线程.

The reason onerror/onload is never called as it would be in a browser is explained in this jsdom issue. An alternate fix that would affect all your tests is offered up in the same issue thread.

这篇关于怎么用Jest测试img.onerror的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆