Spying on a designer using jasmine

I use Jasmine to check if certain objects are created and a method is called on them.

I have a jQuery widget that creates flipcounter objects and calls the setValue method on them. The code for flipcounter is here: https://bitbucket.org/cnanney/apple-style-flip-counter/src/13fd00129a41/js/flipcounter.js

Flip counters are created using:

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

I want to check that flipcounters are created and the setValue method is called on them. My problem is how can I keep track of these objects even before they are created? Am I spying on the constructor and returning fake objects? Sample code really helps. Thanks for your help!:)

Update:

I tried following flipCounter as follows:

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

Then testing to call setValue using flipCounter:

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

The first test to initialize flipCounter is fine, but to test the setValue call, all I get is the 'setValue () method does not exist'. Am I doing it right? Thank!

+47
javascript jasmine spy
Feb 19 2018-12-12T00: 00Z
source share
6 answers

flipCounter is another function, even if it also creates an object. Therefore, you can:

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

to get a spy on it, and do all kinds of checks on it or say:

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

However, this seems redundant. That would be enough:

 var myFlipCounter = new flipCounter("counter", options); expect(myFlipCounter).toBeDefined(); expect(myFlipCounter.getValue(foo)).toEqual(bar); 
+34
Feb 19 2018-12-12T00:
source share

I would suggest using jasmine.createSpyObj() when you want to mock objects with properties that need to be tracked.

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

This checks for interaction with the expected flipCounter interface, which is independent of the flipCounter implementation.

+8
Jun 09 '16 at 20:26
source share

You need to implement a fake constructor for flipCounter , which sets the setValue property to a spy function. Let's say the function you want to test is this:

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

Your specification should look like this:

 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); }); }); 
+4
Oct. 20 '15 at 13:48
source share

The following is not window dependent. Let's say this is the code you want to test -

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

Your test may be -

 var initSpy = jasmine.createSpy('initFlipCounter'); var flipCounter = function(id, options) { initSpy(id, options); } startCountingFlips(flipCounter); expect(initSpy).toHaveBeenCalledWith("counter", {inc:23, pace:500}); 
+3
Jun 05 '14 at 15:33
source share

My version for checking the constructor is to look into the prototype:

 spyOn(flipCounter.prototype, 'setValue').and.callThrough(); var myFlipCounter = new flipCounter("counter", {inc: 23, pace: 500}); expect(flipCounter.prototype.setValue).toHaveBeenCalledTimes(1); 
+1
Sep 20 '17 at 8:35
source share

I don't know how to do this using jasmine mocks, but if you need powerful mocking / spy / stubs, I recommend sinon.js , which works great with jasmine.

From the docs:

A control spy is a function that records the arguments, the return value, the value of this and the eliminated throw (if any) for all its calls. The spy test may be an anonymous function or may wrap an existing function.

Mocks (and mocking expectations) are fake methods (like spies) with pre-programmed behavior (like stubs) as well as programmed expectations. The layout will fail your test if it is not used as expected.

With sinon.js, you can create a flipCounter constructor layout that returns another spy.

Then we claim that the constructor is called using constructorMock.calledWithNew () and claims that the returned spy was called with the return of the returned spy.calledWith (arg1, arg2 ...).

-2
Feb 19 2018-12-12T00:
source share



All Articles