使用Jasmine监听构造函数

我正在使用Jasmine来testing是否创build了某些对象,并调用方法。

我有一个jQuery小部件,创buildflipcounter对象,并调用setValue方法。 flipcounter的代码在这里: https ://bitbucket.org/cnanney/apple-style-flip-counter/src/13fd00129a41/js/flipcounter.js

flipcounters创build使用:

var myFlipCounter = new flipCounter("counter", {inc: 23, pace: 500}); 

我想testingflipcounters是否被创build,并调用setValue方法。 我的问题是,如何在这些对象被创build之前监视它们? 我是否监视构造函数并返回假对象? 示例代码真的有帮助。 谢谢你的帮助! 🙂

更新:

我试过这样的flipCounter间谍:

 myStub = jasmine.createSpy('myStub'); spyOn(window, 'flipCounter').andReturn(myStub); //expectation expect(window.flipCounter).toHaveBeenCalled(); 

然后通过flipCountertestingsetValue调用:

 spyOn(myStub, 'setValue'); //expectation expect(myStub.setValue).toHaveBeenCalled(); 

初始化flipCounter的第一个testing是好的,但为了testingsetValue调用,所有我得到的是一个'setValue()方法不存在'的错误。 我是这样做的吗? 谢谢!

flipCounter只是另一个函数,即使它也碰巧构造一个对象。 因此你可以这样做:

 var cSpy = spyOn(window, 'flipCounter'); 

对其进行间谍,并对其进行各种检查或说:

 var cSpy = spyOn(window, 'flipCounter').andCallThrough(); var counter = flipCounter('foo', options); expect(cSpy).wasCalled(); 

但是,这似乎矫枉过正。 这足以做到:

 var myFlipCounter = new flipCounter("counter", options); expect(myFlipCounter).toBeDefined(); expect(myFlipCounter.getValue(foo)).toEqual(bar); 

我会build议使用jasmine.createSpyObj()当你想嘲笑与需要被窥探的属性的对象。

 myStub = jasmine.createSpyObj('myStub', ['setValue']); spyOn(window, 'flipCounter').andReturn(myStub); 

这将testing与预期的flipCounter接口的交互,而不依赖于flipCounter实现。

你必须为flipCounter实现一个假的构造flipCounter ,将setValue属性设置为间谍函数。 假设您要testing的function是这样的:

 function flipIt() { var myFlipCounter = new flipCounter("counter", {inc: 23, pace: 500}); myFlipCounter.setValue(100); } 

你的规格应该是这样的:

 describe('flipIt', function () { var setValue; beforeEach(function () { setValue = jasmine.createSpy('setValue'); spyOn(window, 'flipCounter').and.callFake(function () { this.setValue = setValue; }); flipIt(); }); it('should call flipCounter constructor', function () { expect(window.flipCounter) .toHaveBeenCalledWith("counter", {inc: 23, pace: 500}); }); it('should call flipCounter.setValue', function () { expect(setValue).toHaveBeenCalledWith(100); }); }); 

以下不依赖于“窗口”。 比方说,这是你想testing的代码 –

 function startCountingFlips(flipCounter) { var myFlipCounter = new flipCounter("counter", {inc: 23, pace: 500}); } 

你的testing可能是 –

 var initSpy = jasmine.createSpy('initFlipCounter'); var flipCounter = function(id, options) { initSpy(id, options); } startCountingFlips(flipCounter); expect(initSpy).toHaveBeenCalledWith("counter", {inc:23, pace:500}); 

我testing一个构造函数的版本是窥探原型:

 spyOn(flipCounter.prototype, 'setValue').and.callThrough(); var myFlipCounter = new flipCounter("counter", {inc: 23, pace: 500}); expect(flipCounter.prototype.setValue).toHaveBeenCalledTimes(1); 

不知道如何使用茉莉花嘲笑,但如果你想要强大的嘲笑/间谍/存根,我build议sinon.js ,这与茉莉花很好地工作。

从文档:

testing间谍是一个函数,它logging参数,返回值,这个值和所有调用抛出的exception(如果有的话)。 testing间谍可以是匿名函数,也可以包装现有的函数。

嘲笑(和模拟期望)是假的方法(如间谍)与预编程的行为(如存根),以及预编程的期望。 如果没有按照预期的方式使用模拟器,testing将会失败。

使用sinon.js,你可以创build一个返回另一个间谍的flipCounter构造函数的模拟。

然后断言使用constructorMock.calledWithNew()调用构造函数,并断言返回的间谍是用returnedSpy.calledWith(arg1,arg2 …)调用的。