如何在茉莉+角形中测试指令的隔离镜的双向绑定

How to test two-way binding with directive's isolateScope in jasmine+angular?

本文关键字:隔离 指令 绑定 测试      更新时间:2023-09-26

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

这是我的指示

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!!
        });
    }));
});

如您所见,我尝试了一些刷新等,认为可能需要发生一些异步操作才能使其工作,但它没有帮助。

测试在等待时达到超时。

我怎样才能让它工作?

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

为了使它起作用,我不得不打电话给isolateScope.$apply().我仍然想对此有一个解释。

呃,

我可能是错的,但看起来你在那里进行绑定的方式没有意义。

// 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指令值

你用属性重载指令声明,并且将范围变量与属性混合在一起(可以通过链接函数访问,但不能访问你正在做的事情)。

编辑:

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