为什么这个 Sinon 模拟有一个不是函数的模拟方法?

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

我想在我的 coffeescript 单元测试中使用测试替身来帮助分离关注点。

我正在将 sinon 与 mocha 结合使用(在 Rails 应用程序与 konacha 的上下文中。)

我正在尝试在这一点上看起来直接来自 the documentation 的东西,它有这个模拟用法的例子:

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);

在我的例子中,我试图模拟一个对象上的函数调用,如下所示:

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

这给出了一个 TypeError 表明 getContext 不是一个函数:

TypeError: canvas.getContext is not a function

模拟似乎已正确设置并得到验证。当省略对 getContext 的调用时,我被告知未满足预期:

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

编译后的JavaScript是这样的,那么:

var canvas;

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

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

canvas.getContext('2d');

canvas.verify();

是什么导致了这个错误?

我想知道我是否对函数参数做了一些奇怪的事情,但我可以在 getContext 调用没有参数的情况下重现它。

您正在尝试直接调用 mock 的方法,但这不是 Sinon.JS 对 mock 的看法。再次考虑示例代码:

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);

被测对象myAPI,不是mock。在上述情况下,类似以下的内容将起作用:

canvas_api = getContext: ->
canvas_mock = sinon.mock(canvas_api)
canvas_mock.expects("getContext").once()
canvas_api.getContext()
canvas_mock.verify()