I'm learning to use Karma and Jasmine for unit-testing in Angular, and am trying to determine how to properly mock out a factory and test that it is called by a controller. The factory makes a simple http request from the ESPN API. When the controller calls it, it passes the response data to an array. What I have so far is based off of this: Angular unit-test controllers - mocking service inside controller. Unfortunately I just can't seem to get it right.
Here is what my controller and factory look like:
angular.module('TeamApp.services',[])
.factory('espnAPIservice',function($http) {
var espnAPI = {};
espnAPI.getTeams = function() {
return $http({
method: 'GET',
url: 'http://api.espn.com/v1/sports/hockey/nhl/teams?'
})
}
return espnAPI;
});
//Calls the espnAPIservice and stores the retrieved information in an array
angular.module('TeamApp.controllers',[])
.controller('TeamCtrl', ['$scope','espnAPIservice',function($scope,espnAPIservice) {
$scope.teams = [];
espnAPIservice.getTeams().success(function (response) {
$scope.teams = response;
});
}]);
angular.module('TeamApp',['TeamApp.services','TeamApp.controllers']);
Here is my test for it so far:
describe('controller: TeamCtrl', function() {
var $scope, ctrl;
//Inject controller module into the factory that it the controller will call
beforeEach(module('TeamApp.controllers', function($provide) {
var espnAPIservice = {
getTeams: function(){}
};
spyOn(espnAPIservice,'getTeams').andReturn('ESPN'); //change return value
$provide.value('espnAPIservice',espnAPIservice);
}));
//Inject the $controller and $rootScope services
beforeEach(inject(function($rootScope, $controller, espnAPIservice) {
//Create a new scope that is the child of $rootScope
$scope = $rootScope.$new();
//Create the controller
ctrl = $controller('TeamCtrl',{$scope: $scope, espnAPIservice: espnAPIservice});
}));
it('should call the getTeams function', function(){
expect($scope.teams).toBe('ESPN');
});
And here is the error I get when I run the test:
PhantomJS 1.9.7 (Windows 7) controller: TeamCtrl should call the getTeams function FAILED
TypeError: 'undefined' is not a function (evaluating 'espnAPIservice.getTeams().success(function (response) {
$scope.teams = response; })')at c:/Users/jquering/Documents/Coding Practice/Angular Practice/nhlStats/app/scripts/teams.js:21
at invoke (c:/Users/jquering/Documents/Coding Practice/Angular Practice/nhlStats/app/lib/angular.js:3762)
at instantiate (c:/Users/jquering/Documents/Coding Practice/Angular Practice/nhlStats/app/lib/angular.js:3773)
at c:/Users/jquering/Documents/Coding Practice/Angular Practice/nhlStats/app/lib/angular.js:6884
at c:/Users/jquering/Documents/Coding Practice/Angular Practice/nhlStats/test/controllers/spec/main.js:18
at invoke (c:/Users/jquering/Documents/Coding Practice/Angular Practice/nhlStats/app/lib/angular.js:3762)
at workFn (c:/Users/jquering/Documents/Coding Practice/Angular Practice/nhlStats/app/lib/angular-mocks.js:2144)undefined
Expected [ ] to be 'ESPN'.
PhantomJS 1.9.7 (Windows 7): Executed 1 of 1 (1 FAILED) ERROR (0.009 secs / 0.008 secs)
Any help would be much appreciated!