2016-07-28 5 views
13

Używam Angular 1.5.5 i Jasmine jako ramy testowe. Obecnie muszę zrobić coś takiego tak, że test przechodzi:

function createController(bindings) { 
    return $componentController('myController', null, bindings); 
} 

beforeEach(inject(function (_$componentController_) { 
    $componentController = _$componentController_; 
})); 

describe('on pages updated', function() { 

    beforeEach(function() { 
     controller = createController({prop1: 0, prop2: 0}); 
     controller.$onInit(); // you see I have to explitcitly call this $onInit function 
    }); 

    it('should update isSelected and currentPage', function() { 
     expect(controller.prop1).toBe(0); 
     expect(controller.prop2).toBe(0); 

     controller.prop1= 1; 
     controller.prop2= 2; 
     controller.$onChanges(controller); // and $onChanges here as well 

     expect(controller.prop1).toBe(1); 
     expect(controller.prop2).toBe(2); 
    }); 

}); 
+1

Dlaczego chcesz wywołać to pośrednio w pierwszej kolejności? '$ onInit' jest wywołaniem cyklu życia, gdy komponent jest zamontowany. Nie ma powodu, aby '$ componentController' kiedykolwiek wywoływał tę funkcję samodzielnie w testach jednostkowych. Powinieneś zdecydowanie uruchamiać te rzeczy, chyba że testujesz komponent jako całość. –

Odpowiedz

0

Nie wiem, czy to pomoże, ale dla elementów testowych Mam następujące

beforeEach(module('templates')); 

var element;   
var scope; 

beforeEach(inject(function ($rootScope, $compile) { 
    scope = $rootScope.$new(); 
    scope.draw = new ol.source.Vector({ wrapX: false }); 
    element = angular.element('<custom-element draw="draw"></custom-element>'); 
    element = $compile(element)(scope); 
})); 

var controller; 
beforeEach(inject(function ($rootScope, $componentController) { 
    scope = $rootScope.$new(); 
    scope.draw = new ol.source.Vector({ wrapX: false }); 
    controller = $componentController('customElement', {draw: new ol.source.Vector({ wrapX: false })}, { $scope: scope }); 
})); 

i $ OnInit () i $ onChanges() uruchamia się, gdy powinny być, samodzielnie,

+0

Czy nie dałoby to kontrolera, który nie jest faktycznie powiązany z komponentem, który kompilujesz? –

+0

Wydaje mi się, że twoją sztuczką jest użycie usługi $ compile do skompilowania dyrektywy, prawda? –

+0

@DanPantry dlaczego tak, kompilujesz komponent i pytasz o kontroler komponentów – elasticrash

0

Wymagałoby to odniesienia do kontrolera ze skompilowanej wersji elementu. Jak pokazano poniżej:

describe('Component: Test Method', function() { 

     beforeEach(inject(function (_$rootScope_) { 
      scope = _$rootScope_.$new(); 
     })); 


     it('should set value of selectedPackage to null after $onChanges event', inject(function ($compile) { 
      // Trigger 1st $onChanges 
      scope.selectedPackage = 'packageCode'; 

      var element = angular.element('<select-my-tv selected-package="selectedPackage"></select-my-tv>'); 
      element = $compile(element)(scope); 
      scope.$digest(); 

      //Extract the Controller reference from compiled element 
      var elementController = element.isolateScope().$ctrl; 

      // Assert 
      expect(elementController.selectedPackage).toBeNull(); 
     })); 
    }); 
}); 
+0

Ale dlaczego miałbyś oczekiwać, że 'selectedPackage' ma wartość' null'? Rozumiem, że '$ onInit' nie jest wywoływany, gdy' 'new'-up kontrolera, ale dlaczego nie jest wywoływany, gdy renderujesz rzeczywisty komponent za pomocą' $ compile'? Z pewnością powinno to wywołać wszystkie haki cyklu życia. – c24w

6

Występuje problem w odniesieniu do tego github: https://github.com/angular/angular.js/issues/14129

zasadzie to działa zgodnie z przeznaczeniem, nie nazywając $onInit lub $onChanges automatycznie.

to nie ma sensu (lub niskie poczucie) wykonywanie $ OnInit, opiszę go: $ componentController jest do kontrolerów przykład rodzaj zamiennik $ kontrolera, ale zamiast tworzyć instancje kontrolerów zarejestrowanych przez controllerProvider it tworzy wystąpienia kontrolerów zarejestrowanych za pomocą dyrektyw (tych, które spełniają definicję komponentu). Tak więc, kiedy już masz instancję kontrolera, możesz wywołać ręcznie $ onInit i cały cykl życia kontrolera, chodzi o to, że testujesz kontroler, a nie dyrektywę (i jej relacje).