AngularJS Jasmine 单元测试 - 永远不会调用控制器方法

AngularJS Jasmine Unit Testing - Controller method is never called

我很难理解 Jasmine。以下测试失败并显示消息 "Expected spy init to have been called. at Object.."

测试

beforeEach(module('myModule'));

it('Should execute myCtrl.init() on controller instantiation', function () {
        var $scope = $rootScope.$new();

        $scope.foo = 'bar';

        var MyCtrl = $controller('MyCtrl', {
            $scope: $scope
        });

        spyOn($scope, 'init');

        expect($scope.init).toHaveBeenCalled();
        expect($scope.foo).toBe('bar');

});

控制器

angular.module('myModule')

.controller('MyCtrl', [
'$scope'
function($scope) {

    $scope.init = $scope.init || function init () {
        $scope.foo = $scope.foo || 'baz';
    };

    $scope.init();

}]);

我错过了什么?

基本上,您不能在创建控制器后设置间谍,否则它不会捕获在控制器调用时调用的方法。但这并不是真正需要测试的东西,因为您可以根据控制器代码判断它在调用控制器时被调用,唯一阻止它被调用的是某种语法错误或其他东西.

你可以测试一些 $scope 属性 比如 $scope.foo 是否被设置为正确的值。

这似乎与

类似的问题

编辑: 如果你真的需要,你可以使用这样的范围模拟(这是你应该做的来模拟你可能对你的控制器的其他依赖项)并注入它而不是 $rootScope 方式,但是你不会有$scope.foo 正在设置,因为 $scope.init 最初不会是未定义的:

var scopeMock;
beforeEach(module('myModule'));

it('Should execute myCtrl.init() on controller instantiation', function () {

    scopeMock = jasmine.createSpyObj('$scope', ['init']);

    var MyCtrl = $controller('MyCtrl', {
        $scope: scopeMock
    });

    //This will be true according to the controller you defined
    expect(scopeMock.init).toHaveBeenCalled();
});