如何编写Karma测试以查看Angular中的控制器是否正在调用工厂函数?

时间:2014-06-12 15:12:49

标签: angularjs unit-testing controller factory karma-jasmine

我正在学习使用Karma和Jasmine在Angular中进行单元测试,并且我正在尝试确定如何正确地模拟工厂并测试它是否由控制器调用。工厂从ESPN API发出一个简单的http请求。当控制器调用它时,它将响应数据传递给数组。到目前为止,我所依据的是:Angular unit-test controllers - mocking service inside controller。不幸的是,我似乎无法做对。

这是我的控制器和工厂的样子:

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']);

到目前为止,这是我对它的测试:

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');
    });

这是我运行测试时得到的错误:

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/jquerring/Documents/Coding Practice/Angular Practice/nhlStats/app/scripts/teams.js:21
            at invoke (c:/Users/jquerring/Documents/Coding Practice/Angular Practice/nhlStats/app/lib/angular.js:3762)
            at instantiate (c:/Users/jquerring/Documents/Coding Practice/Angular Practice/nhlStats/app/lib/angular.js:3773)
            at c:/Users/jquerring/Documents/Coding Practice/Angular Practice/nhlStats/app/lib/angular.js:6884
            at c:/Users/jquerring/Documents/Coding Practice/Angular Practice/nhlStats/test/controllers/spec/main.js:18
            at invoke (c:/Users/jquerring/Documents/Coding Practice/Angular Practice/nhlStats/app/lib/angular.js:3762)
            at workFn (c:/Users/jquerring/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)

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

  

如何正确模拟工厂

beforeEach(module(function ($provide){
    $provide.factory('TheSameName', function (){
      //return your mock here
    });
}));