1

J'essaie de tester une directive avec une propriété à double sens (=). La directive fonctionne dans mon application, mais je ne peux pas faire fonctionner un test unitaire qui teste la liaison bidirectionnelle.Le test de la directive angularjs échoue avec controllerAs, bindToController & isolateScope()

J'ai essayé de faire fonctionner cela pendant des jours. J'ai lu BEAUCOUP d'exemples qui utilisent certaines mais pas toutes les fonctionnalités que je veux utiliser: controllerAs, bindToController & isolateScope(). (Oubliez templateURL, dont j'ai besoin aussi.J'ajouterai que si je peux obtenir ce travail! :)

J'espère que quelqu'un peut me dire comment montrer un changement dans la portée parent reflète dans la portée isolate.

Voici un plunkr qui contient le code ci-dessous:

http://plnkr.co/edit/JQl9fB5kTt1CPtZymwhI

Voici mon application de test:

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

angular.module('myApp').controller('greetingController', greetingController); 
greetingController.$inject = ['$scope']; 
function greetingController($scope) { 
    // this controller intentionally left blank (for testing purposes) 
} 

angular.module('myApp').directive('greetingDirective', 
     function() { 
      return { 
       scope: {testprop: '='}, 
       restrict: 'E', 
       template: '<div>Greetings!</div>', 
       controller: 'greetingController', 
       controllerAs: 'greetingController', 
       bindToController: true 
      }; 
     } 
); 

Et est la spécification ici:

describe('greetingController', function() { 

var ctrl, scope, rootScope, controller, data, template, 
     compile, isolatedScope, element; 

beforeEach(module('myApp')); 

beforeEach(inject(function ($injector) { 

    rootScope = $injector.get('$rootScope'); 
    scope = rootScope.$new(); 
    controller = $injector.get('$controller'); 
    compile = $injector.get('$compile'); 

    data = { 
     testprop: 1 
    }; 

    ctrl = controller('greetingController', {$scope: scope}, data); 
    element = angular.element('<greeting-directive testprop="testprop"></greeting-directive>'); 
    template = compile(element)(scope); 
    scope.$digest(); 
    isolatedScope = element.isolateScope(); 

})); 

// PASSES 
it('testprop inital value should be 1', function() { 
    expect(ctrl.testprop).toBe(1); 
}); 

// FAILS: why doesn't changing this isolateScope value 
// also change the controller value for this two-way bound property? 
it('testprop changed value should be 2', function() { 
    isolatedScope.testprop = 2; 
    expect(ctrl.testprop).toBe(2); 
}); 
}); 

Répondre

3

Vous devez corriger la façon dont vous testez votre directive. Vous modifiez directement isolatedScope d'un objet et vérifie ensuite l'objet ctrl qui n'a aucun rapport avec DOM que vous avez compilé.

Fondamentalement ce que vous devriez faire est dès que vous avez compilé un DOM avec la portée (ici <greeting-directive testprop="testprop"></greeting-directive>). Donc, cette portée tiendra le contexte de faire compilé. En bref, vous pouvez jouer testprop valeur de la propriété. ou la même chose sera disponible à l'intérieur element.scope(). Dès que vous modifiez une valeur dans scope/currentScope. Vous pouvez voir la valeur est mise à jour à l'intérieur de la directive isolatedScope. Une chose que je voudrais mentionner est quand vous faites controllerAs avec bindToController: true, anguleux ajoute propriété avec alias contrôleur à l'intérieur scope qui est nous avons vérifié isolatedScope.greetingController.testprop dans assert

code

describe('greetingController', function() { 

    var ctrl, scope, rootScope, controller, data, template, 
    compile, isolatedScope, currentScope, element; 

    beforeEach(module('myApp')); 

    beforeEach(inject(function($injector) { 

    rootScope = $injector.get('$rootScope'); 
    scope = rootScope.$new(); 
    controller = $injector.get('$controller'); 
    compile = $injector.get('$compile'); 

    data = { testprop: 1 }; 

    ctrl = controller('greetingController', { $scope: scope }, data); 
    element = angular.element('<greeting-directive testprop="testprop"></greeting-directive>'); 
    template = compile(element)(scope); 
    scope.$digest(); 
    currentScope = element.scope(); 
    //OR 
    //currentScope = scope; //both are same 
    isolatedScope = element.isolateScope(); 
    })); 

    // First test passes -- commented 

    it('testprop changed value should be 2', function() { 
    currentScope.testprop = 2; //change current element (outer) scope value 
    currentScope.$digest(); //running digest cycle to make binding effects 
    //assert 
    expect(isolatedScope.greetingController.testprop).toBe(2); 
    }); 

}); 

Demo Plunker

+2

Remerciez vous beaucoup pour votre gentillesse et votre expertise. C'est très utile pour moi. Je vous remercie! Puissiez-vous être béni avec la prospérité et la richesse à tous les niveaux. – DanBKC

+2

@DanBKC Hé, merci mon pote pour la bénédiction, depuis des années j'aide les autres. Mais vous êtes celui qui a donné un si bon commentaire, merci;) Il m'a encouragé à faire plus de contribution :) –