如何使用Jest测试asnyc代码(或使用jsdom测试“image.onload”)

时间:2017-04-06 09:36:58

标签: javascript reactjs testing jestjs jsdom

[已编辑]:我已经以承诺方式更改了我的代码。

我正在写作与facebook创建的this启动器的反应,我是一个关于测试的新手。

现在我有一个关于图像的组件,它有一个检查图像大小的功能:

import React, { Component } from 'react';


class ImagePart extends Component {
    .....
    //  check size.
    checkSize(src, width, height){
        this.loadImg(src)
        .then((obj) => {
            return (obj.width >= width && obj.height >= height)
            ? true : false;
        })
        .catch((msg)=> {
            dosomething
        });
    }
    // load image and return a promise.
    loadImg(src){
        return new Promise((resolve, reject) => {
            let imageObj = new Image();
            imageObj.onload = (evt) => {
                resolve(evt.target);
            }
            imageObj.error = (err) =>{
                reject(err);
            }
            imageObj.src = src; 
        })
    }
    .....
}

测试片段:

import React from 'react';
import ReactDOM from 'react-dom';
import ImagePart from './ImagePart';



it('checking image size without error', () => {
    const image = new ImagePart();
    const img300_300 = 'https://someImage.png';
    expect(image.loadImg(img300_300).width).resolves.toBe(300);
    // ??? test checkSize
});

运行测试后,我收到此错误:

  

TypeError:无法读取未定义的属性'toBe'

问题是:

  1. 如何以正确的方式测试`loadImg?
  2. 测试checkSize的一般模式是什么?
  3. 谢谢。

2 个答案:

答案 0 :(得分:2)

在测试异步代码时,您应该可以使用done回调。 https://facebook.github.io/jest/docs/asynchronous.html

在你的情况下我会做

it('checking image size without error', (done) => {
    const image = new ImagePart();
    const img300_300 = 'https://someImage.png';
    expect(image.checkSize(img300_300,200,200)).toEqual(true);
    expect(image.checkSize(img300_300,300,300)).toEqual(true);
    expect(image.checkSize(img300_300,300,200)).toEqual(false);
    expect(image.checkSize(img300_300,200,300)).toEqual(false);
    expect(image.checkSize(img300_300,400,400)).toEqual(false);
    done();
});

答案 1 :(得分:2)

checkSize的当前实现是异步的,始终返回undefined

您应该使用callback或返回Promise

function checkSizeWithCallback(src, width, height, callback) {
  const image = new Image();
  image.onload = evt => {
    const result = evt.target.width >= width && evt.target.height >= height;
    callback(null, result);
  };
  image.onerror = // TODO: handle onerror
  image.src = src; 
}


it('...', done => {
  checkSizeWithCallback(/* args */, (err, result) => {
    expect(result).toEqual(true);
    done(err);
  });
});
function checkSizeWithPromise(src, width, height) {
  return new Promise((resolve, reject) => {
    const image = new Image();
    image.onload = evt => {
      const result = evt.target.width >= width && evt.target.height >= height;
      resolve(result);
    };
    image.onerror = // TODO: handle onerror
    imageObj.src = src; 
  });
}


it('...', () => {
  return checkSizeWithPromise(/* args */)
    .then(result => {
      expect(result).toEqual(true);
  });
});