Mock document.getElemetById('.form').getContext('2d') using sinon
Asked Answered
J

2

5

I'm using karma, mocha, chai, sinon and Angular mocks for my unit testing. In my $scope.loadChart, I'm drawing a chart in my canvas tag. I'm using http://www.chartjs.org/ to draw the charts.

Chartjs requires this piece of code, document.getElemetById('#canvas').getContext('2d'). How do I stub this in Sinon? My test is stuck with this line.

Jamiejamieson answered 26/5, 2015 at 8:59 Comment(0)
B
8

You could stub document.getElementById and have it return a canvas object that is stubbed and programmed to return a context object of your choosing...

//Create your fake canvas and context objects
var canvas = document.createElement('canvas');
var fakeContext = {}; //Replace this with whatever you want your fake context to be

//Have `canvas.getContext('2d')` return your fake context
sinon.stub(canvas, 'getContext');
canvas.getContext.withArgs('2d').returns(fakeContext);

//Have `document.getElementById('canvas')` return your canvas
sinon.stub(document, 'getElementById');
document.getElementById.withArgs('canvas').returns(canvas);
Balcke answered 28/7, 2015 at 14:59 Comment(3)
This does not work for me. I am getting an error message: TypeError: Attempted to assign to readonly propertyDevilish
Which line of the example causes that error for you?Balcke
document.getElementById.withArgs('canvas'), I am trying to mock createElement() thoughDevilish
F
1

You should wrap that DOM access in a method. Then you can mock that method.

var DomAccess = function() {} 
DomAccess.prototype.get2dCanvas = function() {
    return document.getElementById('#canvas').getContext('2d');
}

var domAccess = new DomAccess();
var context = domAccess.get2dContext();

You can now mock this class the usual way with sinon.

Fiddlehead answered 26/5, 2015 at 9:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.