Skip to content

Instantly share code, notes, and snippets.

@johngian
Last active January 12, 2024 08:56
Show Gist options
  • Save johngian/71ee878aa736276491673dc88a564e63 to your computer and use it in GitHub Desktop.
Save johngian/71ee878aa736276491673dc88a564e63 to your computer and use it in GitHub Desktop.
Mock imported class from module using sinon

Context

Sinon design is mostly focused on mocking/stubbing function instead of class definitions. Its easy to mock class functions (via mocking/stubbing the prototype) but having a side effect on constructor makes things complicated.

Solution

One work around to this is using the sinon.createStubInstance(constructor) method and then add a fake call to the class.

const rectangle = require("./rectangle.js");
class RectangleCollection {
constructor(rectangles) {
this.rectangles = [];
for (const rec in rectangles) {
this.rectangles.push(new rectangle.Rectangle(rec[0], rec[1]));
}
}
getArea() {
return this.rectangles.reduce((rec) => rec.getArea(), 0);
}
}
module.exports = {
RectangleCollection,
};
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
getArea() {
return this.width * this.height;
}
}
module.exports = {
Rectangle,
};
const assert = require("assert");
const sinon = require("sinon");
const collection = require("./collection.js");
const rectangle = require("./rectangle.js");
describe("Area test", function () {
it("should calculate the area of a collection", function () {
const stubbedRectangle = sinon.createStubInstance(rectangle.Rectangle, {
getArea: sinon.stub().returns(1),
});
sinon.stub(rectangle, "Rectangle").callsFake((...args) => {
console.log("Mock called");
return stubbedRectangle;
});
const c = new collection.RectangleCollection([(2, 5), (3, 4), (1, 9)]);
assert(c.getArea, 3);
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment