AngularJS Jasmine单元测试 - 永远不会调用Controller方法

时间:2015-09-17 20:33:59

标签: angularjs unit-testing jasmine tdd

我很难绕过Jasmine。以下测试失败,并显示消息"已调用预期的spy init。在对象.."

测试

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

}]);

我错过了什么?

1 个答案:

答案 0 :(得分:3)

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

您可以测试是否将某些$ scope属性(如$ scope.foo)设置为正确的值。

这似乎与AngularJs unit test - Check if "Init" function was called

类似

编辑: 如果你真的需要,你可以使用像这样的范围模拟(这是你应该做的,以模拟你可能对控制器的其他依赖)并注入它而不是$ 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();
});