我正在试着弄清楚如何使用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属性。
非常感谢任何帮助。
答案 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)
如果要创建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先生把它放在一起