带有服务的单元测试控制器

时间:2016-06-15 17:33:44

标签: angularjs unit-testing jasmine karma-jasmine

我正在尝试对注入了服务的控制器进行单元测试。无论我似乎尝试什么,我都会收到错误。任何帮助我实现这一目标的帮助将非常感激。我正在使用Angular / Karma / Jasmine来运行我的测试。

似乎有很多类似故事的帖子,但感觉它可能不重复 - 如果是的话道歉。

我的控制器看起来像这样:

(function() {
  angular
    .module('blah')
    .controller('AdminController', AdminController);

  /* @ngInject */
  function AdminController($scope, toastr, adminService) {
    activate();

    /**
     * Controller initialisation.
     */
    function activate() {
      getAllUsers();
    }

    /**
     * Gets all users.
     */
    function getAllUsers() {
      adminService.getAllUsers()
        .then(function(response) {
          $scope.users = response.data;
        })
        .catch(function(error) {
          toastr.error('Unable to load users', 'Error');
          console.log(error);  
        });
     }        
  }
})();

我的服务看起来像这样:

(function() {
  angular
    .module('blah')
    .factory('adminService', adminService);

  /* @ngInject */
  function adminService($http, environmentConfig) {
    var service = {
      getAllUsers: getAllUsers
    };

    return service;

    /**
     * Gets all user objects.
     */
    function getAllUsers() {
      return $http.get(environmentConfig.apiBaseUrl + '/user');
    }
  }
})();

我的单元测试看起来像这样:

describe('AdminController', function() {
  var ctrl,
      adminService,
      $scope;

  var listOfTestUsers = [
    { name: 'Dave', id: 1 },
    { name: 'Bob', id: 2 },
    { name: 'Bill', id:3 }
  ];

  beforeEach(function() {
    module('blah');
  });

  beforeEach(inject(function($rootScope, $controller) {
    adminService = {
      getAllUsers: function() {}
    };

    spyOn(adminService, 'getAllUsers').and.returnValue(listOfTestUsers);

    $scope = $rootScope.$new();

    ctrl = $controller('AdminController', {
      $scope: $scope,
      adminService: adminService
    });
  }));

  describe('The getAllUsers function should exist', function() {
    it('should work', function() {
      expect(ctrl).toBeDefined();
    });
  });
});

使用Karma运行我的Jasmine测试时出现此错误:

TypeError: adminService.getAllUsers(...).then is not a function

3 个答案:

答案 0 :(得分:2)

以下是我发现代码错误的一些事情。

    之前使用过
  1. .catch。调用.then时有两个回调,一个成功回调和一个错误回调。这就是我在致电adminService.getAllUsers时所做的事情。

  2. 对于您获得的TypeError: adminService.getAllUsers(...).then is not a function。你没有正确地模仿getAllUsers。我在testCases文件中完成了这个。它返回一个名为then的函数,该函数在之前不可用。

  3. <强>控制器

    &#13;
    &#13;
    (function() {
      angular
        .module('blah', [])
        .controller('AdminController', AdminController);
    
      /* @ngInject */
      function AdminController($scope, toastr, adminService) {
        $scope.greeting = "Hello World!";
    
        /**
         * Gets all users.
         */
        $scope.getAllUsers = function() {
          adminService.getAllUsers()
            .then(function(response) {
              $scope.users = response.data;
            }, function(error) {
              toastr.error('Unable to load users', 'Error');
              console.log(error);
            });
        }
    
        activate();
    
        /**
         * Controller initialisation.
         */
        function activate() {
          $scope.getAllUsers();
        }
      }
    })();
    &#13;
    &#13;
    &#13;

    environmentConfig常量。用你的替换它。

    &#13;
    &#13;
    (function() {
      angular.module('blah').constant('environmentConfig', {
        apiBaseUrl: 'https://www.something.com'
      })
    })();
    &#13;
    &#13;
    &#13;

    toastr服务。将其替换为您的

    &#13;
    &#13;
    (function() {
      angular
        .module('blah')
        .factory('toastr', toastr);
    
      /* @ngInject */
      function toastr() {
        var service = {
          error: error
        };
    
        return service;
    
        /**
         * Gets all user objects.
         */
        function error(a, b) {
          console.log("Here's the error : ", a);
        }
      }
    })();
    &#13;
    &#13;
    &#13;

    <强> adminService

    &#13;
    &#13;
    (function() {
      angular
        .module('blah')
        .factory('adminService', adminService);
    
      /* @ngInject */
      function adminService($http, environmentConfig) {
    
        /**
         * Gets all user objects.
         */
        function getAllUsers() {
          return $http.get(environmentConfig.apiBaseUrl + '/user');
        }
    
        var service = {
          getAllUsers: getAllUsers
        };
    
        return service;
      }
    })();
    &#13;
    &#13;
    &#13;

    测试用例

    &#13;
    &#13;
    describe('controller: AdminController', function() {
      var scope, $scope, toastr, adminService, AdminController, flag, $q;
      flag = 'success';
    
      var listOfTestUsers = [{
        name: 'Dave',
        id: 1
      }, {
        name: 'Bob',
        id: 2
      }, {
        name: 'Bill',
        id: 3
      }];
    
      beforeEach(module('blah'));
    
      beforeEach(inject(function($controller, $rootScope, _toastr_, _adminService_, _$q_) {
    
        scope = $rootScope.$new();
        toastr = _toastr_;
        adminService = _adminService_;
        $q = _$q_;
    
    
        spyOn(adminService, 'getAllUsers').and.callFake(function() {
          return flag === 'success' ? $q.when(listOfTestUsers) : $q.reject("Error");
        });
    
        AdminController = $controller('AdminController', {
          $scope: scope,
          toastr: _toastr_,
          adminService: _adminService_
        });
      }));
    
      describe('The getAllUsers function should exist', function() {
        it('should work', function() {
          expect(AdminController).toBeDefined();
        });
      });
    });
    &#13;
    &#13;
    &#13;

    希望这有帮助。

答案 1 :(得分:0)

您的控制器代码导致错误。你应该调用$ scope.getAllUsers();在你的激活功能中,不是&#34; getAllUsers()&#34;。

答案 2 :(得分:0)

您的实际错误是您的模拟服务没有“getAllUsers”功能,这是一个带有调整http://pastebin.com/LwG0CzUW的粘贴框

如果您愿意,可以调整测试以将实际服务称为以下pastebin。

http://pastebin.com/RSP4RfF9

相关问题