Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this Sinon mock have a mocked method that is not a function?

I would like to use test doubles in my coffeescript unit tests to help with separation of concerns.

I am using sinon with mocha (in the context of a Rails app with konacha.)

I am trying what at this point seems straight out of the documentation, which has this example of mock usage:

var myAPI = { method: function () {} };

var spy = sinon.spy();
var mock = sinon.mock(myAPI);
mock.expects("method").once().throws();

PubSub.subscribe("message", myAPI.method);
PubSub.subscribe("message", spy);
PubSub.publishSync("message", undefined);

mock.verify();
assert(spy.calledOnce);

In my case I'm trying to mock a function call on an object as follows:

canvas = sinon.mock getContext: (arg) ->
canvas.expects("getContext").once()
canvas.getContext('2d')
canvas.verify()

This gives a TypeError indicating that getContext is not a function:

TypeError: canvas.getContext is not a function

The mock seems to be setup and getting verified correctly. When omitting the call to getContext, I am informed that an expectation was not met:

ExpectationError: Expected getContext([...]) once (never called)

The compiled JavaScript looks like this, then:

var canvas;

canvas = sinon.mock({
  getContext: function(arg) {}
});

canvas.expects("getContext").once();

canvas.getContext('2d');

canvas.verify();

What could account for this error?

I was wondering if I was doing something strange with the function argument, but I can reproduce this without an argument to the getContext call.

like image 452
Joseph Weissman Avatar asked Jul 04 '15 15:07

Joseph Weissman


1 Answers

You are trying to call methods on the mock directly, but this isn't how Sinon.JS thinks of mocks. Consider the example code again:

var myAPI = { method: function () {} };

var spy = sinon.spy();
var mock = sinon.mock(myAPI);
mock.expects("method").once().throws();

PubSub.subscribe("message", myAPI.method);
PubSub.subscribe("message", spy);
PubSub.publishSync("message", undefined);

mock.verify();
assert(spy.calledOnce);

The subject under test is myAPI, not mock. In the case above, something like the following will work:

canvas_api = getContext: ->
canvas_mock = sinon.mock(canvas_api)
canvas_mock.expects("getContext").once()
canvas_api.getContext()
canvas_mock.verify()
like image 150
Joseph Weissman Avatar answered Nov 13 '22 00:11

Joseph Weissman