2013-07-12 13 views
18

Próbuję przetestować dyrektywę za pomocą karmy i jaśminu, która wykonuje kilka rzeczy. Po pierwsze dlatego, że używa szablonu template i po drugie definiuje kontroler. Może to nie być poprawna terminologia, ale w deklaracji tworzy kontroler. Aplikacja Angular jest tak skonfigurowana, że ​​każda jednostka jest zawarta w jej własnym module. Na przykład, wszystkie dyrektywy są zawarte w module app.directive, wszystkie kontrolery są zawarte w app.controller, a wszystkie usługi są zawarte w app.service itp.Jednostka testująca dyrektywę, która definiuje kontroler w AngularJS

Aby jeszcze bardziej skomplikować, kontroler określony w tej dyrektywie ma pojedyncza zależność i zawiera funkcję, która wykonuje żądanie HTTP w celu ustawienia wartości w $ scope. Wiem, że mogę sfałszować tę zależność za pomocą $ httpBackend, aby symulować wywołanie $ http i zwrócić odpowiedni obiekt do wywołania tej funkcji. Robiłem to wiele razy w innych testach jednostkowych, które stworzyłem i mam całkiem dobry pomysł na tę koncepcję.

Poniższy kod zapisany jest w CoffeeScript.

Oto moja dyrektywa:

angular.module('app.directive') 
     .directive 'exampleDirective', [() -> 
     restrict: 'A' 
     templateUrl: 'partials/view.html' 
     scope: true 
     controller: ['$scope', 'Service', ($scope, Service) -> 
      $scope.model = {} 
      $scope.model.value_one = 1 

      # Call the dependency 
      Service.getValue() 
      .success (data) -> 
       $scope.model.value_two = data 
      .error -> 
       $scope.model.value_two = 0 
     ] 
     ] 

Oto serwis zależność:

angular.module("app.service") 
     .factory 'Service', ['$http', ($http) -> 

     getValue:() -> 
     options.method = "GET" 
     options.url = "example/fetch" 

     $http _.defaults(options) 

Oto widok:

<div> 
     {{model.value_one}} {{model.value_two}} 
    </div> 

Uprościłem to trochę, ponieważ moim celem jest tylko zrozumienie, jak to połączyć, mogę to zrobić. Powodem, dla którego konstruuję to w ten sposób, jest to, że początkowo tego nie stworzyłem. Pracuję nad pisaniem testów dla istniejącego projektu i nie mam możliwości jego konfiguracji w żaden inny sposób. Podjąłem próbę napisania testu, ale nie mogę zrobić tego, co chcę.

Chcę przetestować, aby sprawdzić, czy wartości są powiązane z widokiem, a jeśli to możliwe, aby przetestować, czy kontroler prawidłowo tworzy wartości.

Oto co mam:

'use strict' 

    describe "the exampleDirective Directive", -> 

     beforeEach module("app.directive") 
     beforeEach module("app/partials/view.html") 

     ServiceMock = { 
     getValue :() -> 

     options.method = "GET" 
     options.url = "example/fetch" 

     $http _.defaults(options) 
     } 

    #use the mock instead of the service 
    beforeEach module ($provide) -> 
     $provide.value "Service", ServiceMock 
     return 

    $httpBackend = null 
    scope = null 
    elem = null 

    beforeEach inject ($compile, $rootScope, $injector) -> 

    # get httpBackend object 
    $httpBackend = $injector.get("$httpBackend") 
    $httpBackend.whenGET("example/fetch").respond(200, "it works") 

    #set up the scope 
    scope = $rootScope 

    #create and compile directive 
    elem = angular.element('<example-directive></example-directive>') 
    $compile(elem)(scope) 
    scope.$digest() 

Nie wiem, jak blisko jestem, czy to jest jeszcze prawidłowa. Chcę móc stwierdzić, że wartości są poprawnie powiązane z widokiem. Użyłem przykładu Vojtajiny do skonfigurowania html2js w moim pliku karma.js, aby umożliwić mi pobieranie widoków. Zrobiłem wiele badań, aby znaleźć odpowiedź, ale potrzebuję pomocy. Mam nadzieję, że programista mądrzejszy niż ja wskaże mi właściwy kierunek. Dziękuję Ci.

Odpowiedz

29

Utwórz element w karmie, a następnie użyj funkcji .controller() z nazwą swojej dyrektywy, aby pobrać kontroler. Na swoim przykładzie, wymień kilka ostatnich wierszy z nich:

elem = angular.element('<div example-directive></div>'); 
$compile(elem)($rootScope); 
var controller = elem.controller('exampleDirective'); 

uwaga, że ​​biorąc pod uwagę, jak zdefiniowano swoją dyrektywę, powinny być przez atrybut, a nie jako element. Nie jestem też w 100% pewny, ale nie potrzebuję scope.$digest; zwykle po prostu wkładam wszystko, co musi być zastosowane w bloku scope.$apply(function() {}).

+0

i czym jest obiekt elementu (linia 3)? powinien być na miejscu?ale wciąż się nie definiuje –

+0

Wierzę, że środkowa linia powinna być: var element = $ compile (elem) ($ rootScope); –

+0

Wierzę też, że ostatnia linia powinna być zmienną controller = elem.controller ("exampleDirective"); –

Powiązane problemy