Ava使用promise测试图像加载:测试返回的promise从未解决过

时间:2018-02-17 10:55:20

标签: javascript unit-testing ava

我想测试我的promise函数来加载图像,这段代码看起来像这样:

protected function validator(array $data)
{
    $data['email'] = strtolower($data['email']);
    return Validator::make($data, [
        'firstName' => 'required|string|max:255',
        'lastName' => 'required|string|max:255',
        'email' => 'required|string|email|max:255|unique:user,usrEmail',
        'password' => 'required|string|min:6|confirmed',
    ]);  
}

当我在浏览器中使用我的承诺时,它可以正常工作:

function imagePromise() {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.addEventListener('load', () => resolve(true));
    img.addEventListener('error', () => reject(false));
    img.src = 'http://78.media.tumblr.com/tumblr_lr9mx5Axur1qlyuwso1_1280.jpg';
  });
}

但是,当我使用avabrowser-env测试我的承诺时,ava会返回错误:

imagePromise().then((result) => console.log(result));
// fulfill the promise and log the result: true

我的测试文件如下所示:

Promise returned by test never resolved

请注意,由于浏览器兼容性,我同时尝试了import test from 'ava'; function imagePromise() { return new Promise((resolve, reject) => { const img = new Image(); img.addEventListener('load', () => resolve(true)); img.addEventListener('error', () => reject(false)); img.src = 'http://78.media.tumblr.com/tumblr_lr9mx5Axur1qlyuwso1_1280.jpg'; }); } test('load image with promise', (t) => { return imagePromise().then((result) => { t.is(result, true); }); }); addEventListener / onload方法,而浏览器env已经configured to work with ava。有什么我想念的吗?

2 个答案:

答案 0 :(得分:1)

我最终使用browser-env(它本身使用jsdom)修复了我的测试。我做了small repo for people interested

我的第一个错误是我忘了安装canvas-prebuilt,这允许jsdom操纵imagescanvas元素。

// install browser-env and canvas-prebuilt
// (https://github.com/jsdom/jsdom#loading-subresources)
yarn add browser-env canvas-prebuilt -D

我的第二个错误,我忘了在browser-env文件的test/helpers/setup-browser-env.js声明中添加特殊配置:

require('browser-env')(['window', 'document', 'Image'], {
  resources: 'usable',
});

然后我们可以从test/test.js

运行我们的图片加载承诺测试
import test from 'ava';

function imagePromise() {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.addEventListener('load', () => resolve(true));
    img.addEventListener('error', () => reject(false));
    // an heavy 4k wallpaper to check if promise is resolved after a long time
    img.src = 'https://www.wallpaperup.com/wallpaper/download/991808/8000/5224';
  });
}

test('load image with promise', (t) => {
  return imagePromise().then((result) => {
    t.is(result, true);
  });
});

要运行测试,您可以执行ava但我强烈建议添加--verbose标志,因为它有助于使用--watch标志进行调试(为您的测试进行实时重载)。

答案 1 :(得分:0)

如何将图片创建从imagePromise移至ImageClass?之后,您将控制承诺解决/拒绝

import test from "ava";
import { EventEmitter } from "events";

function imagePromise(img) {
    return new Promise((resolve, reject) => {
        img.addEventListener("load", () => resolve(true));
        img.addEventListener("error", () => reject(false));
        img.src = "http://78.media.tumblr.com/tumblr_lr9mx5Axur1qlyuwso1_1280.jpg";
    });
}

test("load image with promise", t => {
    class ImageClass extends EventEmitter {
        addEventListener(type, fn) {
            this.on(type, fn);
        }
    }

    const image = new ImageClass();

    process.nextTick(() => image.emit("load"));

    return imagePromise(image).then(result => {
        t.is(result, true);
    });
});