Javascript:使用Sinon模拟构造函数

时间:2013-01-28 19:20:13

标签: javascript unit-testing constructor mocking sinon

我正在试着弄清楚如何使用sinon来模拟构造函数。我有一个函数,通过调用接受一些参数的构造函数来创建多个小部件。我想验证构造函数是否使用正确的参数调用了正确的次数,但我不想实际构造小部件。以下链接似乎解释了一种模拟构造函数的简单方法,但它对我不起作用:

Spying on a constructor using Jasmine

http://tinnedfruit.com/2011/03/25/testing-backbone-apps-with-jasmine-sinon-2.html

当我对存根构造函数进行以下调用时:

sinon.stub(window, "MyWidget");

我收到以下错误:

Uncaught TypeError: Attempted to wrap undefined property MyWidget as function 

在Chrome中进行调试时,我看到MyWidget显示在Scope Variables的Local部分中,但是窗口外没有MyWidget属性。

非常感谢任何帮助。

9 个答案:

答案 0 :(得分:16)

我需要一个解决方案,因为我的代码调用了new运算符。我想模拟新调用创建的对象。

var MockExample = sinon.stub();
MockExample.prototype.test = sinon.stub().returns("42");
var example = new MockExample();
console.log("example: " + example.test()); // outputs 42

然后我使用重新连接将其注入我正在测试的代码中

rewiredModule = rewire('/path/to/module.js');
rewiredModule.__set__("Example", example);

答案 1 :(得分:7)

来自sinonjs的官方网站:

  

用stub函数替换object.method。可以通过调用object.method.restore()来恢复原始函数; (或stub.restore();)。如果属性不是>已经是函数,则抛出异常,以帮助避免在存根方法时出现拼写错误。

这只是说明要为其创建存根的函数必须是对象对象的成员。

说清楚;你打电话

sinon.stub(window, "MyWidget");

MyWidget函数需要在全局范围内(因为您将 window 作为参数传递)。但是,正如您已经说过的,此函数位于本地范围内(可能在对象文字或命名空间中定义)。

在javascript中,每个人都可以访问全局范围,但不是相反。

检查你声明MyWidget函数的位置,并将容器对象作为第一个参数传递给sinon.stub()

答案 2 :(得分:2)

我使用Mockery模拟了一个构造函数/函数而没有任何问题。

var mockery = require('mockery');
var sinon = require('sinon');

mockery.enable({
  useCleanCache: true,
  warnOnReplace: false,
  warnOnUnregistered: false
});

exports.Client = function() {/* Client constructor Mock */};
var ClientSpy = sinon.spy(exports, 'Client');
mockery.registerMock('Client', ClientSpy);

var Factory = require('Factory'); // this module requires the Client module

你应该可以像上面的例子那样应用Sinon Spy。

确保在测试后禁用或重置Mockery!

答案 3 :(得分:2)

刚刚在documentation.

中找到了这个
  

如果要创建MyConstructor的存根对象,但不想调用构造函数,请使用此实用程序函数。

     

var stub = sinon.createStubInstance(MyConstructor)

答案 4 :(得分:1)

使用Sinon 4.4.2,我可以模拟这样的实例方法:

sinon.stub(MyClass.prototype, myMethod).resolves(tesObj)

我需要一条模拟行,类似于:

let someData = await new MyClass(token).myMethod(arg1, arg2)

此处提供了类似的解决方案: Stubbing a class method with Sinon.js

答案 5 :(得分:0)

我错误地输入了sinon.stub.throws(expectedErr)而不是sinon.stub().throws(expectedErr),从而遇到了此错误。我之前犯了类似的错误,之前没有遇到过这个特殊的消息,所以它把我扔了。

答案 6 :(得分:0)

使用sinon.createStubInstance(MyES6ClassName),然后使用new关键字调用MyES6ClassName时,将返回MyES6ClassName实例的存根。

答案 7 :(得分:0)

我知道原来的问题现在已经有点老了,但是,您是否尝试对类的原型进行存根处理?

const myStub = sinon.stub(MyClass.prototype, 'myMethodReturnsFalse').returns(true)
const myInstance = new MyClass()
expect(myInstance.myMethodReturnsFalse()).equal(true)

答案 8 :(得分:-9)

在经过一些调整之后,我能够让StubModule工作,最明显的是在存根模块中需要时传入async:false作为配置的一部分。

感谢Davis先生把它放在一起