2013-07-12 12 views
18

Sto provando a testare una direttiva usando Karma e Jasmine che fa un paio di cose. Innanzitutto, utilizza un templateUrl e in secondo luogo definisce un controller. Questa potrebbe non essere la terminologia corretta, ma crea un controller nella sua dichiarazione. L'applicazione Angolare è configurata in modo che ogni unità sia contenuta all'interno del proprio modulo. Ad esempio, tutte le direttive sono incluse nel modulo app.directive, tutti i controller sono contenuti all'interno di app.controller e tutti i servizi sono contenuti all'interno di app.service, ecc.Unit test di una direttiva che definisce un controller in AngularJS

Per complicare ulteriormente le cose, il controller definito in questa direttiva ha una singola dipendenza e contiene una funzione che effettua una richiesta $ http per impostare un valore su $ scope. So che posso prendere in giro questa dipendenza usando $ httpBackend mock per simulare la chiamata $ http e restituire l'oggetto corretto alla chiamata di questa funzione. L'ho fatto numerose volte negli altri test di unità che ho creato e ho una buona conoscenza di questo concetto.

Il codice seguente è scritto in CoffeeScript.

Qui è la mia direttiva:

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 
     ] 
     ] 

Ecco il servizio di dipendenza:

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

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

     $http _.defaults(options) 

Qui è la vista:

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

L'ho semplificato un po ', poiché il mio obiettivo è solo capire come collegarlo, posso prenderlo da lì. Il motivo per cui lo sto strutturando in questo modo è perché inizialmente non l'ho creato. Sto lavorando alla scrittura di test per un progetto esistente e non ho la possibilità di configurarlo in altro modo. Ho fatto un tentativo di scrivere il test, ma non riesco a farlo fare quello che voglio.

Voglio testare per vedere se i valori sono vincolati alla vista e, se possibile, anche per verificare se il controller sta creando i valori correttamente.

Ecco quello che ho:

'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() 

non so quanto vicino sono io, o se questo è anche corretto. Voglio essere in grado di affermare che i valori sono legati alla vista correttamente. Ho usato l'esempio di Vojtajina per impostare html2js nel mio file karma.js per permettermi di catturare le viste. Ho fatto molte ricerche per trovare la risposta, ma ho bisogno di aiuto. Spero che un programmatore più saggio di me possa indicarmi la giusta direzione. Grazie.

risposta

29

Creare l'elemento in karma, quindi utilizzare la funzione .controller() con il nome della direttiva per afferrare il controller. Per il vostro esempio, sostituire l'ultimo paio di righe con questi:

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

nota, che dato come è stata definita la vostra direttiva, che dovrebbe essere per attributo, e non come un elemento. Inoltre, non sono sicuro al 100%, ma non penso che sia necessario il scope.$digest; di solito metto tutto ciò che deve essere applicato in un blocco scope.$apply(function() {}).

+0

e qual è l'elemento oggetto (3a riga)? dovrebbe essere elem in atto?ma non riesco a trovare undefine –

+0

Credo che la linea di mezzo dovrebbe essere: var element = $ compile (elem) ($ rootScope); –

+0

Credo anche che l'ultima riga dovrebbe essere var controller = elem.controller ('exampleDirective'); –

Problemi correlati