FF5Ninja FF5Ninja - 5 months ago 12
AngularJS Question

What type of spy to use for testing

I know when you use

spyOn
you can have different forms like
.and.callFake
or
.andCallThrough
. I'm not really sure which one I need for this code I'm trying to test...

var lastPage = $cookies.get("ptLastPage");
if (typeof lastPage !== "undefined") {
$location.path(lastPage);
} else {
$location.path('/home'); //TRYING TO TEST THIS ELSE STATEMENT
}
}


Here is some of my test code:

describe('Spies on cookie.get', function() {
beforeEach(inject(function() {
spyOn(cookies, 'get').and.callFake(function() {
return undefined;
});
}));
it("should work plz", function() {
cookies.get();
expect(location.path()).toBe('/home');
expect(cookies.get).toHaveBeenCalled();
expect(cookies.get).toHaveBeenCalledWith();
});
});


I've tried a lot of different things, but I'm trying to test the
else
statement. Therefore I need to make
cookies.get == undefined
.
Everytime I try to do that though, I get this error:

Expected '' to be '/home'.


The value of
location.path()
never changes when
cookies.get()
is equal to
undefined
. I think I'm using the spyOn incorrectly?

Follow-up on my mock values:

beforeEach(inject(
function(_$location_, _$route_, _$rootScope_, _$cookies_) {
location = _$location_;
route = _$route_;
rootScope = _$rootScope_;
cookies = _$cookies_;
}));


Follow-up on the functions:

angular.module('buildingServicesApp', [
//data
.config(function($routeProvider) {
//stuff
.run(function($rootScope, $location, $http, $cookies)


No names on these functions, therefore how do I call the
cookies.get
?

Answer

Right now, you're testing that the location.path() function works as designed. I'd say you should leave that testing to the AngularJS team :). Instead, verify that the function was called correctly:

  describe('Spies on cookie.get', function() {
    beforeEach((function() { // removed inject here, since you're not injecting anything
      spyOn(cookies, 'get').and.returnValue(undefined); // As @Thomas noted in the comments
      spyOn(location, 'path');
    }));
    it("should work plz", function() {
      // cookies.get(); replace with call to the function/code which calls cookies.get()
      expect(location.path).toHaveBeenCalledWith('/home');
    });
  });

Note that you shouldn't be testing that your tests mock cookies.get, you should be testing that whatever function calls the first bit of code in your question is doing the right thing.