簡體   English   中英

帶有服務的單元測試控制器

[英]Unit test controller with service in it

我正在嘗試對注入了服務的控制器進行單元測試。 無論我如何嘗試,都會出現錯誤。 任何幫助我實現這一目標的幫助將不勝感激。 我正在使用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

這是我發現代碼有誤的幾件事。

  1. .catch較早使用。 .then有兩個回調,一個成功回調和一個錯誤回調。 這就是我在調用adminService.getAllUsers所做的adminService.getAllUsers

  2. 對於TypeError: adminService.getAllUsers(...).then is not a function您要獲取TypeError: adminService.getAllUsers(...).then is not a function 您沒有正確地模擬getAllUsers。 我已經在testCases文件中做到了。 它返回一個名為then的函數,該函數先前不可用。

調節器

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

environmentConfig常量。 用你的替換它。

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

敬酒服務。 用你的替換

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

adminService

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

測試用例

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

希望這可以幫助。

您的控制器代碼導致了錯誤。 您應該調用$ scope.getAllUsers();。 在您的激活函數中,而不是“ getAllUsers()”。

您的實際錯誤是您的模擬服務沒有功能'getAllUsers'的事實,這里是帶有調整的粘貼箱http://pastebin.com/LwG0CzUW

如果您願意,可以調整測試以通過以下pastebin調用實際服務。

http://pastebin.com/RSP4RfF9

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM