单元测试中的指令隔离范围

时间:2014-05-03 15:07:37

标签: javascript angularjs unit-testing

我有一个相当复杂的指令,下面是一个简化的表格。

http://plnkr.co/edit/QV2QyZlknGyN3zTiv3w4?p=preview

如果删除兄弟元素,它会起作用:http://plnkr.co/edit/rMeCyKiMm4jPqh2NFKPf?p=preview

当我的模板中有其他兄弟html标签时,如评论一样,

console.log(el.isolateScope()) --> undefined
console.log(el.children().scope()) --> isolated scope

我期望通过el.isolateScope()获得隔离的指令范围。为什么不定义?如果存在其他元素,为什么行为不同(仍然,指令不是其他元素的子元素,而是兄弟元素)

JS:

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

app.directive('myTest', function () {
    return {
        restrict: 'E',
        scope: {},
        replace: true,
        template: '<div><div>far boo</div></div>',
        link: function (scope, element, attrs, controller) {
            scope.msg = 'bar';        
        },
        controller: function($scope){
            $scope.msg = 'foo';
        }
    };
});

规格:

describe('myTest directive:', function () {

    var scope, compile, validHTML;

    //validHTML = '<my-test></my-test>';
    validHTML = '<script type="text/ng-template" id="directive/propTmplAdd.html"><div></div></script><my-test></my-test>';

    beforeEach(module('plunker'));

    beforeEach(inject(function($compile, $rootScope){
        scope = $rootScope.$new();
        compile = $compile;
    }));

    function create() {
        var elem, compiledElem;
        elem = angular.element(validHTML);
        compiledElem = compile(elem)(scope);
        scope.$digest();

        return compiledElem;    
    }

    it('should have a scope on root element', function () {  
        var el = create();

        console.log('isolateScope', el.isolateScope())
        console.log('ch isolateScope', el.children().scope())
        console.log('ctrl', el.controller('myTest'))


        expect(el.isolateScope()).toBeDefined();
        expect(el.isolateScope().$id).not.toEqual(scope.$id);
    });

    it('should have a populated scope', function(){
        var el = create();
        expect(el.isolateScope().msg).toBeDefined();
        expect(el.isolateScope().msg).toEqual('bar');   
    });
});

1 个答案:

答案 0 :(得分:2)

代码中create()函数返回的jqLit​​e包装对象将包含两个元素。

el[0]将是:

<script type="text/ng-template" id="directive/propTmplAdd.html" class="ng-scope"><div></div></script>

el[1]将是:

<div class="ng-scope ng-isolate-scope"><div>far boo</div></div>

当调用el.isolateScope()时,它将在第一个元素上调用,而第一个元素没有。

您必须以不同方式编译元素或重新包装jqLit​​e中的正确元素。

例如:

it('should have a populated scope', function() {

  var elements = create();
  var element = angular.element(elements[1]);

  expect(element.isolateScope().msg).toBeDefined();
  expect(element.isolateScope().msg).toEqual('bar');
});