角度单元测试:参数'fn'不是函数,得到了Object

时间:2016-01-08 17:24:48

标签: angularjs unit-testing jasmine karma-runner

当我尝试实例化单元测试的设置阶段时,会发生此错误。我是一个单元测试指令,它有自己的控制器。出于最佳实践目的,我总是可以将controllerAs属性添加到指令中以为控制器分配名称,但如果我这样做,我会得到相同的错误。

describe('myDirective', function() {        

    beforeEach(module('app'));
    beforeEach(module('app/directives/directive.html'));

    var theArgs = { 
        arg1 : [],
        arg2 : 'id',
        arg3 : [],
        arg4 : '',
        arg5 : false
    };  

    beforeEach(inject(function($templateCache, _$compile_, _$rootScope_, $controller) {
        template = $templateCache.get('app/directives/directive.html');
        $templateCache.put('app/directives/directive.html', template);
        $compile = _$compile_;
        $rootScope = _$rootScope_;
        scope = $rootScope.$new();
        scope.args = theArgs;
        ctrl = $controller({
            $scope: scope
        });
    }));

    it('should compile', function() {
        var myElement = angular.element('<div my-directive args="theArgs" ></div>');
        var element = $compile(myElement)(scope);

        // Grab scope. Depends on type of scope.
        scope = element.isolateScope() || element.scope();
        // Grab controller instance
        controller = element.controller(ctrl);
        $rootScope.$digest();        

        // Mock the directive's controller's add() function
        scope.add();                
     });    
});

此块中发生错误:

ctrl = $controller({
    $scope: scope
});

由于控制器没有名称,我在上面的代码块中没有传递一个名称。这不应该自己抛出错误,对吧?我不认为我的业力配置存在问题,因为我的其他500项测试都已通过。

第二个错误是controller = element.controller(ctrl);引发的,它找不到ctrl变量。该错误是有道理的,因为它是由第一个错误引起的,但我无法弄清楚如何修复第一个错误。

更新:添加了指令代码以显示控制器的定义方式。它从未被赋予名称,它是匿名的,我没有使用controllerAs属性,因为它返回错误。

app.directive('myDirective', function() {
    var dirController = ['$scope', function($scope) {
        $scope.add = function() { ... };
    }];

    return {
        restrict: 'A',
        scope: {
            args: '='
        },
        templateUrl: '/path/to/template.html',
        controller: dirController
    };
});

1 个答案:

答案 0 :(得分:1)

问题恰恰在于此代码部分:

ctrl = $controller({
    $scope: scope
});

由于$controller需要第一个参数的控制器名称,然后是对象文字中的注射剂。 例如:告诉它应该创建哪个控制器:

ctrl = $controller('MyControllerName', {
    $scope: scope
});