【问题标题】:Angular unit testing: Argument 'fn' is not a function, got Object角度单元测试:参数'fn'不是函数,得到对象
【发布时间】:2016-01-08 17:24:48
【问题描述】:

当我尝试实例化单元测试的设置阶段时,会发生此错误。我正在对一个指令进行单元测试,它有自己的控制器。出于最佳实践目的,我始终可以将 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
});

由于控制器没有名称,我没有在上面的代码块中传递它。不过,这本身不应该引发错误,对吧?我认为我的 karma 配置没有问题,因为我的其他 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
    };
});

【问题讨论】:

    标签: angularjs unit-testing jasmine karma-runner


    【解决方案1】:

    问题就在于这段代码:

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

    因为$controller 需要控制器的名称作为第一个参数,然后是对象字面量中的可注入对象。 例如:告诉它应该创建哪个控制器:

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

    【讨论】:

    • 谢谢,但是当我添加一个名字时,我得到一个不同的错误:Argument 'myController' is not a function, got undefined
    • 您的控制器名称是什么?你能告诉我你是如何实现这部分的吗?
    猜你喜欢
    • 1970-01-01
    • 2013-04-15
    • 1970-01-01
    • 2019-11-20
    • 2017-03-30
    • 2017-01-03
    • 1970-01-01
    • 2016-11-30
    • 2021-11-12
    相关资源
    最近更新 更多