I'm currently trying to test some Promise heavy functions in the codebase. This snippet also has the added joy of an event listener as well.
How would I go about testing this?
const createImage = url =>
new Promise((resolve, reject) => {
const image = new Image();
image.addEventListener("load", () => resolve(image));
image.addEventListener("error", error => reject(error));
image.setAttribute("crossOrigin", "anonymous"); // needed to avoid cross-origin issues on CodeSandbox
image.src = url;
});
export default createImage;
I got a solution to this issue via Reddit, here's the answer for those interested:
It's not about testing Promises, it's about testing Image load operation. Jest uses JSDOm, and we can look into its implementation for HTMLImage. Unfortunately there is no code to trigger events like load or error.
So we cannot mock request(say using Nock to respond with 500 for particular URL) and validate Promise is rejected(which would be the best). Instead we have to rely on implementation details and inject into Image.prototype:
let onLoadFn, onErrorFn;
Image.prototype.addEventListener = jest.fn((type, fn) => {
if (type === 'load') onLoadFn = fn;
if (type === 'error') onErrorFn = fn;
});
and later either
const result = yourFunction('someurl');
onLoadFn();
return expect(result).resolves.toEqual(expect.any(Image));
or
const result = yourFunction('someurl');
onErrorFn("test");
return expect(result).rejects.toEqual("test");
Also it looks like a known thing in JSDOm that events are not dispatched at least for load/error