【问题标题】:How to test asnyc code with Jest ( or test "image.onload" with jsdom )如何使用 Jest 测试 asnyc 代码(或使用 jsdom 测试“image.onload”)
【发布时间】:2017-09-01 06:07:28
【问题描述】:

[已编辑]:我已经用 promise 方式更改了我的代码。

我正在用 facebook 创建的 this starter 编写反应,我是一个测试新手。

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

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; 
        })
    }
    .....
}

并测试sn-p:

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 的一般模式是什么?

谢谢。

【问题讨论】:

    标签: javascript reactjs testing jestjs jsdom


    【解决方案1】:

    您应该能够在测试异步代码时使用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();
    });
    

    【讨论】:

      【解决方案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);
        });
      });
      

      【讨论】:

      • 谢谢!我认为使用 Promise 解决了我的“未定义”问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-30
      • 1970-01-01
      • 2022-11-10
      • 2017-11-11
      • 2020-06-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多