如何在jasmine + angular中使用指令的isolateScope测试双向绑定?

时间:2014-12-28 07:04:52

标签: javascript angularjs jasmine

我想在指令更改后测试父作用域获取新值,但由于某种原因它不起作用。

这是我的指示

angular.module('myModule').directive('myDirective', function(){
    return {
        template: 'just a template',
        restrict: 'A',
        scope: {
            'model' : '=myDirective'
        }, 
        link: function postLink( scope ){
            scope.changeModelValue = function( value ){
                scope.model = value;
            }
        }
    }
});

这是我的测试

describe('the test', function(){

    var scope, isolateScope, element;

    var reset = function(){
        scope = null;
        isolateScope = null;
        element = null;
    };

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

    var setup = inject(function( $compile ){
        element = angular.element('<div my-directive="item"></div>');
        element = $compile(element)(scope);
        scope.$digest();
        isolateScope = element.children().scope();
    });

    it('should work', inject(function( $timeout ){
        scope.item = null; 
        setup();
        expect(typeof(isolateScope.changeModelValue)).toBe('function'); // works!
        isolateScope.changeModelValue('new value');
        expect(isolateScope.model).toBe('new value'); // works!

        // tried all the of this - but didn't help..
        waitsFor(function(){
            try{ $timeout.flush(); } catch (e) { }
            try{ scope.$digest.flush(); } catch (e) { }
            try{ isolateScope.$digest(); } catch (e) { }

            return scope.reportLesson !== null;
        });

        runs(function(){
            expect(scope.item).toBe('new value'); //fails!!
        });

    }));
});

正如你所看到的那样,我尝试了一些冲洗等等,想想也许有一些异步行为需要发生才能使它发挥作用,但它并没有帮助。

测试在waitsFor上达到超时。

我怎样才能让它发挥作用?

2 个答案:

答案 0 :(得分:1)

事实证明$digest$timeout.flush不会影响绑定。

为了使其有效,我不得不致电isolateScope.$apply()。我仍然想对此作出解释。

答案 1 :(得分:-1)

呃我可能错了,但看起来你做绑定的方式没有意义。

// 2-way-bind the value of 'model' in this scope to the myDirective attribute in the parent scope
scope: {
    'model' : '=myDirective'
},

如果那是'= item',那么根据你的需要,这是有道理的,所以试试吧。

你正在做的另一件事有点奇怪:

// Give my directive an attribute which is the 'item' element from the scope
element = angular.element('<div my-directive="item"></div>');

所以这有点奇怪,请阅读这个答案:AngularJS Directive Value

您正在使用属性重载指令声明,并且您正在将范围变量与属性混合(可以通过链接功能访问,但不能通过链接功能访问)。

编辑:

作为最后一点,你应该相信AngularJS正确地进行了绑定。编写这类测试非常耗时,您应该专注于程序逻辑。