AngularJs 单元测试 - 检查是否调用了 "Init" 函数

AngularJs unit test - Check if "Init" function was called

我正在使用 jasmine 作为测试框架,并且我有以下要测试的控制器。我总是有一个 Init() 函数,我在其中放置对此控制器的初始化调用。

现在我想测试控制器初始化时是否调用了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 函数中的原始原型上创建 spy

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

事实就是这样,你不能也确实不需要。你不能的原因是因为你在控制器构造函数上调用 init(),即在实例化时,当你调用 $controller 服务在你的测试中实例化控制器时发生。所以你设置间谍为时已晚。您可能不需要,因为如果控制器被实例化,则肯定会调用 init 方法。但是,如果您在 init 中进行任何特定的 service/dependency 调用,您可以监视这些模拟并设置期望值。

你的期望是: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 在实例化之前。