Javascript Ava测试图像加载承诺:测试返回的承诺从未解决

Javascript Ava测试图像加载承诺:测试返回的承诺从未解决,javascript,unit-testing,ava,Javascript,Unit Testing,Ava,我想测试我的promise函数以加载图像,代码如下所示: function imagePromise() { return new Promise((resolve, reject) => { const img = new Image(); img.addEventListener('load', () => resolve(true)); img.addEventListener('error', () => reject(false));

我想测试我的promise函数以加载图像,代码如下所示:

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';
  });
}
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);
  });
});
当我在浏览器中使用我的承诺时,它工作正常:

imagePromise().then((result) => console.log(result));
// fulfill the promise and log the result: true
但是,当我使用and测试我的承诺时,ava返回一个错误:

Promise returned by test never resolved
我的测试文件如下所示:

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';
  });
}
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
/
onerror
方法,并且浏览器env已被禁用。我缺少什么吗?

将图像创建从
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);
    });
});

最后,我使用
browser env
(它本身使用
jsdom
)修复了测试。我做了一个:

我的第一个错误是忘记安装
canvas预构建
,它允许
jsdom
操作
图像
canvas
元素

// install browser-env and canvas-prebuilt
// (https://github.com/jsdom/jsdom#loading-subresources)
yarn add browser-env canvas-prebuilt -D
我的第二个错误是,我忘记在
test/helpers/setup browser env.js
文件中的
browser env
声明中为测试添加特殊配置:

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
标志进行调试(对于您的测试来说是一种实时重新加载)。

我已经给出了一个粗略的示例,说明了我希望如何执行操作,但在这之后,我有一个带有子加载程序类的加载程序类(例如ImageLoader、AudioLoader等)。但我终于解决了我的测试问题,我打算在几分钟内把它作为答案写下来。谢谢你的帮助。