user1806692
user1806692

Reputation: 143

Jasmine spyOn and how to use spies generally

I am starting out in JS unit testing and having a hard time getting my head around how to create meaningful tests with Jasmine spies.

it('should take an array of shopping items', function() {
  spyOn(checkObj, 'getTotal');
  checkObj.getTotal([1, 2, 3]);
  expect(checkObj.getTotal).toHaveBeenCalledWith(jasmine.any(Array));
});

Using the above excerpt of test I created as an example I cant see how this is a useful test as my call to getTotal is hard coded inside the spec. But at the same time I would like to ensure the param passed is an array and not some other type...its the hard coding that I am sure is wrong somehow.

Could someone offer a bit of guidance on how I should think/approach this type of testing scenario

Upvotes: 2

Views: 2195

Answers (1)

Vladimir M
Vladimir M

Reputation: 4489

Well, spies are useful for a bit different scenario. Much depends on how you yourself define the scope of your unit test as well. If you do the minimal possible unit (i.e. method) then lets imagine the following:

var x = function() { }
x.prototype.f1 = function() { 
        //do something 
        },
x.prototype.f2 = function(){
          // do something else
          this.f1();
        }

Now, in your unit test for f2 you are not interested in how f1 works inside. so, you make a spy on it:

var a = new x();
a.f1 = jasmine.createSpy("spy-on-f1");
expect(a.f1).not.toHaveBeenCalled();
a.f2();
expect(a.f1).toHaveBeenCalled();

For example, for angularjs applications, I often mock whole services with spies, just to isolate the algorithm in testing.

As a bonus, you can actually replace the real call with some fake function like this:

a.f1 = jasmine.createSpy("fake-spy").and.callFake(function(){
    // do something predictible or return global variable that can be set externaly
});

Upvotes: 1

Related Questions