如何使用jasmine测试从其依赖项输入的控制器?

时间:2016-02-15 09:19:35

标签: angularjs jasmine

服务 userService:

(function() {
    'use strict';
    angular.module('kprModule',[]).service('userService', userService);

    function userService() {
        function getUsername(){
            return 'krihsnaChaitanya';
        };
        return{
            getUsername:getUsername
        }
    }
})();

控制器 Account.js:

(function() {
    'use strict';
    angular
    .module('bsp',[])
    .controller('Account', Account);
    function Account(userService) {

        var vm = this;

        vm.title = 'Accounts';
        vm.username = userService.getUsername();
    }
})();

Jasmine测试用例:

describe('Account', function() { 
  var scope, controller, userServiceMock; 
  beforeEach(module('bsp')); 
  beforeEach(function() {
    userServiceMock = {
      getUsername: function(){} 
    };
  });

  beforeEach(inject(function($rootScope, $controller) {
    scope = $rootScope.$new();
    controller = $controller('Account', {
      'userService': userServiceMock
    });
  }));

  describe('testing Title',function(){
    it('checkTitle', function(){
      expect(controller.userService.getUsername()).toEqual('krihsnaChaitanya'); 
    }); 
  }); 
});

我的问题是如何测试我的控制器中分配给userService.getUsername();的{​​{1}}?

1 个答案:

答案 0 :(得分:0)

在使用应用程序时,只需为我自己的帮助重新格式化您的应用程序。我不知道您是否故意将服务和控制器放在不同的模块中,但这样做会将它们置于不同的角度应用程序中,并使它们彼此不可见,而不会依赖于另一个。在你的情况下,' bsp'应该依赖于kprModule'并定义如下:

angular.module('bsp',['kprModule']);

然而,为了简单起见,我将它们放在同一个模块中,以示例如何在控制器内对服务进行单元测试。

'use strict';
var kpr = angular.module('kprModule', []);
kpr.service('userService', userService);
function userService() {
    function getUsername() {
        return 'krihsnaChaitanya';
    }

    return {
        getUsername: getUsername
    }
}

kpr.controller('Account', Account);
function Account(userService) {
    var vm = this;

    vm.title = 'Accounts';
    vm.username = userService.getUsername();
}

要实际测试服务,您无法模拟服务。或者,如果你模拟服务,那么你实际上需要让它做你需要的测试所需的东西,比如在mock中实现getUsername函数。因为你实际上是在尝试测试服务本身,虽然我删除了模拟并将实际服务注入到你的测试中,所以真实的东西可以传递给控制器​​。

然后,如果我们稍微更改您的测试以在控制器上查找用户名属性,因为该服务从未明确地在' vm'我们得到了以下测试:

describe('Account', function() {
    var scope, controller, userService;
    beforeEach(module('kprModule'));
    beforeEach(inject(function(_userService_) {
        userService = _userService_;
    }));

    beforeEach(inject(function($rootScope, $controller) {
        scope = $rootScope.$new();
        controller = $controller('Account', {
            'userService': userService
        });
    }));

    describe('testing Title',function(){
        it('checkTitle', function(){
            expect(controller.username).toEqual('krihsnaChaitanya');
        });
    });
});

如果您有充分的理由将服务和控制器保存在单独的模块中,则必须确保1.使它们相互依赖,并且2.在引用两者时将两者都加载到测试中。