如何使用qunit测试angularjs指令?

时间:2014-02-20 06:36:32

标签: angularjs-directive qunit

在我们的团队中使用qunit,我正在试图弄清楚如何使用qunit测试指令。我正在关注示例https://egghead.io/lessons/angularjs-unit-testing-a-directive

这是指令:

var app = angular.module("app", []);

app.directive("ehSimple", function() {
    return function(scope, element) {
        element.addClass("plain");
    }
})

到目前为止,这是我的qunit测试

var injector = angular.injector(['ng', 'app']);

test('ehSimple directive', function() {

    var element;
    var $scope;

    injector.invoke(['$compile', function($compile, $rootScope) {
        $scope = $rootScope;
        element = angular.element('<div eh-simple>{{ 2 + 2}}</div>');
        $compile(element)($rootScope);
    }]);
    $scope.$digest();
    console.log(element.html());

    ok(element.html() == '4');
});

当我尝试用卡拉进行测试时,我得到了:

Died on test #1 @/home/.../tests/qunit/test_directives.js:34
: [ng:areq] Argument 'scope' is required

任何想法都非常令人沮丧?

1 个答案:

答案 0 :(得分:4)

您遇到的问题是您没有在注入器调用行中一致地配置调用函数。你的invoke()表示该函数接受单个参数$ compile,但函数定义需要两个参数$ compile和$ rootScope。因此$ rootScope在函数体中是未定义的,并且在轨道上会出现关于范围缺失的奇怪错误。具体来说,调用行应为:

injector.invoke(['$compile', '$rootScope', function($compile, $rootScope) { ... }]);

这是Angular函数声明和调用中的常见模式 - 它的替代方法是:

injector.invoke(function($compile, $rootScope) { ... });

即。没有包装数组定义参数。如果您不缩小代码,则此有效。如果你缩小它,Angular就无法自省函数来确定传入的正确参数,因此显式列出了参数名称的数组形式。

请参阅$injector docs on function annotation获取(稍微)更多信息。

请注意,通过避免不必要的invoke():

,可以更简单地编写测试
test('ehSimple directive', function() {
    var element;
    var $scope = injector.get('$rootScope');
    var $compile = injector.get('$compile');

    element = angular.element('<div eh-simple>{{ 2 + 2}}</div>');
    $compile(element)($scope);
    $scope.$digest();
    console.log(element.html());

    ok(element.html() == '4');
});

因为所有的invoke()都在为你做了一堆inject.get()并用结果调用你的函数。