Подтвердить что ты не робот

Директива элемента тестирования - не может получить доступ к изолированным областям методов во время тестов

У меня есть следующая директива.

directivesModule.directive('wikis', function() {
var urlRegex = new RegExp('^(https?)://.+$');

return {
    restrict: 'E', 
    templateUrl: 'templates/wiki-list.html',
    scope: {
        wikis: '='
    },
    link: function(scope, element, attrs) {
        scope.newWikiURL = '';

        scope.$watch('wikis', function() {
            if (scope.wikis == undefined || scope.wikis.length === 0) {
                scope.class = 'hide';
            } else {
                scope.class = 'show';
            }
        }, false);

        scope.addWiki = function() {
            if (scope.wikis == undefined) {
                scope.wikis = [];
            }

            var nw = scope.newWikiURL;
            if (nw != undefined && nw.trim() != '' && urlRegex.exec(nw)) { 
                scope.wikis.push(nw);
                scope.newWikiURL = '';
            }
        }

    }
};

});

Когда я его протестирую:

describe('Wikis Directive Test Suite', function() {
    var scope, elem, directive, linkFn, html;

    beforeEach(function() {
        html = '<wikis wikis=''></wikis>';

        inject(function($compile, $rootScope) {
            scope = $rootScope.$new();
            scope.wikis = [];

            elem = angular.element(html);

            $compile(elem)(scope);

            scope.$digest();
        });

    });

    it('add Wiki should add a valid wiki URL to artist', function() {
        var url = 'http://www.foo.com';
        scope.newWikiURL = url;
        scope.addWiki();

        expect(scope.wikis.length).toBe(1);
        expect(scope.wikis[0]).toBe(url);
        expect(scope.newWikiURL).toBe('');
    });
});

Я получаю сообщение о том, что Object не имеет метода addWiki. Я попытался отладить его, и функция ссылки не вызывается во время теста. Я подозреваю, почему метод addWiki не входит в область действия. Кто-нибудь знает, почему я получаю эту ошибку?

Кстати, нормальная практика заключается в том, чтобы добавить некоторую логику в функцию ссылки директивы, так как это был бы сам контроллер? Поскольку я смотрю на код, я знаю, что это почему на самом деле я делаю.
4b9b3361

Ответ 1

  • Вам нужно загрузить модуль, содержащий вашу директиву, иначе angular не знает, что <wikis>

  • В вашей директиве создается область изоляции, поэтому после ее компиляции вам нужно получить новую область с помощью elem.isolateScope()

Итак, с этими изменениями:

describe('Wikis Directive Test Suite', function() {
    var $scope, scope, elem, directive, linkFn, html;

    beforeEach(module('app'));

    beforeEach(function() {
        html = '<wikis></wikis>';

        inject(function($compile, $rootScope, $templateCache) {
            $templateCache.put('templates/wiki-list.html', '<div>wiki template</div>');

            $scope = $rootScope.$new();
            $scope.wikis = [];

            elem = angular.element(html);

            $compile(elem)($scope);

            scope = elem.isolateScope();
            scope.$apply();
        });

    });

    it('add Wiki should add a valid wiki URL to artist', function() {
        var url = 'http://www.foo.com';
        scope.newWikiURL = url;
        scope.addWiki();

        expect(scope.wikis.length).toBe(1);
        expect(scope.wikis[0]).toBe(url);
        expect(scope.newWikiURL).toBe('');
    });
});

http://jsfiddle.net/QGmCF/1/

Ответ 2

Согласно angular 1.2.0 docs, способ получить область выделения - через метод isolateScope

  • scope() - извлекает область текущего элемента или его родителя.

  • isolateScope() - извлекает область выделения, если она привязана непосредственно к текущему элементу. Этот getter должен использоваться только для элементов, содержащих директиву, которая запускает новую область выделения. Вызов области() для этого элемента всегда возвращает исходную область неизолирования.

Angular doc - раздел jQuery/jqLite Дополнительно

BREAKING CHANGE: jqLite # scope()