AngularJs单元测试 - 检查" Init"功能被称为

时间:2015-02-08 16:03:33

标签: angularjs unit-testing jasmine

我正在使用茉莉作为testframework,我想要测试以下控制器。我总是有一个Init()函数,我在那里为这个Controller安排初始化调用。

现在我想测试初始化​​控制器时是否调用了Init函数。

function UnitTestsCtrl() {
   var that = this;
   this.Init();
}

UnitTestsCtrl.prototype.Init = function() {
    var that = this;
    //Some more Stuff
}

angular.module("unitTestsCtrl", [])
       .controller("unitTestsCtrl", UnitTestsCtrl);

但我无法检查是否在控制器创建时调用了Init函数。我知道我的例子不起作用,因为间谍在创建后设置在Init函数上。

describe('Tests Controller: "UnitTestsCtrl"', function() {
var ctrl;

   beforeEach(function() {
         module('app.main');
         inject(function ($controller) {
            ctrl = $controller('unitTestsCtrl', {});
         });
   });

   it('Init was called on Controller initialize', function () {
       //thats not working
       spyOn(ctrl, 'Init');
       expect(ctrl.Init).toHaveBeenCalled();
   });
});

解决方案:

在beforeEach函数

中创建原始Prototype上的间谍
 beforeEach(function() {
     module('app.main');

     spyOn(UnitTestsCtrl.prototype, 'Init');

     inject(function ($controller) {
        ctrl = $controller('unitTestsCtrl', {});
     });
 });

 it('Init was called on Controller initialize', function () {
        expect(ctrl.Init).toHaveBeenCalled();
 });

1 个答案:

答案 0 :(得分:3)

它的方式,你不能,你真的不需要。你不能这样做是因为你在控制器构造函数上调用init(),即在实例化时,当你调用$controller服务来实例化测试中的控制器时会发生这种情况。所以你设置间谍太迟了。您可能不需要,因为如果控制器是实例化的,那么init方法肯定会被调用。但是,如果你在init中进行任何特定的服务/依赖调用,你可以监视那些模拟并设定期望。

您的期望是:Service Call executed因此请为该服务创建一个间谍并设置期望。

示例:

   var myService = jasmine.createSpyObj('myService', ['someCall']);
   myService.someCall.and.returnValue($q.when(someObj));
   //...


  ctrl = $controller('unitTestsCtrl', {'myService':myService});

并设置myService的someCall方法的期望值。

 expect(myService.someCall).toHaveBeenCalled();

如果您真的想要监视init,那么您需要访问规范中的UnitTestsCtrl构造函数,然后您需要在其原型方法init上设置间谍实例化。