функция ссылки директивы AngularJS никогда не вызывалась в тесте Jasmine

Я не понимаю, почему функция ссылки моей директивы никогда не вызывается в тесте Jasmine. Я сделал простой пример.

Вот моя директива (TestDirective.js):

'use strict';

angular.module('comp-one').directive('test',function(){

    return{
        restrict:'E',
        templateUrl:'components/comp-one/html/TestTemplate.html',
        scope:true,
        link:function(scope){
            scope.test='xxx';
        }
    };
});

А это тестовый пример:

'use strict';

describe('testDirective',function(){
    var $compile, $rootScope, element;

    beforeEach(module('comp-one'));
    beforeEach(module('templates'));

    beforeEach(inject(function(_$rootScope_,_$compile_){
        $compile = _$compile_;
        $rootScope = _$rootScope_;
    }));

    it('xxx', function(){
        var html = '<test></test>';
        element = $compile(html)($rootScope);
        $rootScope.$digest();

        expect( $rootScope.test ).toBe('xxx');
    });
});

Тесты не удались, потому что функция ссылки никогда не вызывается, и поэтому переменная xxx не определена. Я ожидал, что функция ссылки будет выполнена "$compile(html)($rootScope);" утверждение. Когда я устанавливаю точку останова в функции ссылки и запускаю приложение (не тест) в браузере, вызывается функция ссылки.

Я запускаю тесты с помощью Karma, который также находит файл, как я вижу в выводе консоли:

Processing "D:/JWS/test/workspace/bla/app/components/comp-one/scripts/TestDirective.js".

Изменить:

Хорошо, я узнал, что тест проходит успешно, когда я установил область действия на false. Но есть ли способ протестировать функцию ссылки с изолированной областью?


person Wanderdüne    schedule 17.02.2016    source источник


Ответы (1)


Вызывается функция ссылки. Вы найдете значение в области видимости элемента, а не в $rootScope.

Используйте element.isolateScope().test вместо $rootScope.test в ожидаемой части.

person Tome Pejoski    schedule 17.02.2016
comment
Кроме того, не используйте $rootScope напрямую при компиляции контроллера. В операторе beforeEach присвойте $scope = $rootScope.new(), затем вместо этого используйте $scope. - person Tome Pejoski; 17.02.2016
comment
Хорошо, спасибо за подсказку. Можете ли вы объяснить, в чем разница между $rootScope и областью действия, которую я получу из $rootScope.$new()? Я знаю, что это создает дочернюю область, но кажется, что оба они ведут себя одинаково в модульном тесте. - person Wanderdüne; 18.02.2016
comment
Причина проста: $rootScope должен быть как можно более чистым. Это означает, что ваш код будет легко тестируемым, читабельным, и не возникнет никаких странных ошибок, поскольку $rootScope является общим для всего кода AngularJS в вашем приложении. - person Tome Pejoski; 18.02.2016