Jonathan
Jonathan

Reputation: 9151

Test async onload handler with Mocha/Chai/Sinon

I'm trying to add a test for a function that should be called after image.onload.
I'm attaching the handler in the RenderObject constructor which sets all the dimensions for objects with that image source on load.
The code works as expected when I run it but I fail to create a test that succesfully proves this.

import { assert, expect } from "chai";
import "mocha";
import * as Sinon from "sinon";
import { IRenderObect } from "../interfaces/IRenderObject";
import { Point } from "./Point";
import { RenderObject } from "./RenderObject";

const imageSrc = "../../images/test80x100.png";
const initialPosition = new Point(10, 20);
const objectList = RenderObject.getObjectList();

afterEach(done => {
  objectList.forEach(o => o.destroy());
  done();
});

describe("RenderObject", () => {
  it("When a new image is loaded setDimensionsForImage is called", () => {
    const spy = Sinon.spy(RenderObject.setDimensionsForImage);
    const renderObject = { imageSrc: "xxx", initialPosition };
    const object = new RenderObject(renderObject);

    assert.ok(spy.calledOnce); // Fails as it should be async
  });

  it("Object has correct dimensions for image", done => {
    const spy = Sinon.spy(RenderObject.setDimensionsForImage);
    const renderObject = { imageSrc, initialPosition };
    const object = new RenderObject(renderObject);

    window.setTimeout(() => {
      try {
        expect(object.width).to.equal(80); // Also fails...
        expect(object.height).to.equal(100);
      } finally {
        done();
      }
    }, 1000);
  });

  it("Add new objects to the object list", () => {
    const renderObject = { imageSrc, initialPosition };
    const object = new RenderObject(renderObject);

    expect(objectList.length).to.equal(1);
  });

  it("Remove objects from the object list once destroyed", () => {
    const renderObject = { imageSrc, initialPosition };
    const object = new RenderObject(renderObject);
    object.destroy();

    expect(objectList.length).to.equal(0);
  });
});

How can I test that dimensions are correctly applied after image load?

edit:
I think my test setup can't load images. I guess I need to set use Chrome headless...

Upvotes: 0

Views: 212

Answers (1)

user2347763
user2347763

Reputation: 489

Surely, setTimeout is not a member of the window object and inside of the arrow function, the object passed to the describe callback is this. Didn't you get an error? You could try using it so,

it("Object has correct dimensions for image", done => {

}).timeout(()=>{

}, 1000)

Upvotes: 0

Related Questions