2012-09-04 12 views
28

Ecco il file di prova specifica:Come iniettare dipendenze nel test di gelsomino per un elemento angolare

describe('Test main controller', function(){ 
     it('Should initialize value to Loading', function(){ 
      $scope = {} 
      ctrl = new mainNavController($scope) 
      expect($scope.wksp_name).toBe('Loading') 
     }) 
    }) 

Ecco il file di controllo

function mainNavController($scope) { 
    $scope.wksp_name = 'Loading...' 
    $scope.$on('broadCastWkspNameEvent', function (e, args) { 
     $scope.wksp_name = args 
    }) 
} 

mainNavController.$inject=['$scope'] 

Ma il mio test non riesce dicendo Object #<Object> has no method '$on'

Sto usando la configurazione di base del gelsomino.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
    "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
    <title>Jasmine Spec Runner</title> 

    <link rel="shortcut icon" type="image/png" href="testlib/jasmine-1.2.0/jasmine_favicon.png"> 
    <link rel="stylesheet" type="text/css" href="testlib/jasmine-1.2.0/jasmine.css"> 
    <script type="text/javascript" src="testlib/jasmine-1.2.0/jasmine.js"></script> 
    <script type="text/javascript" src="testlib/jasmine-1.2.0/jasmine-html.js"></script> 

    <!-- include source files here... --> 
    <script type="text/javascript" src="/static_files/js/test-specs/main-nav-spec.js"></script> 

    <!-- include spec files here... --> 
    <script type="text/javascript" src="/static_files/js/common/jquery/latest.js"></script> 
    <script type="text/javascript" src="/static_files/js/common/angular/angular-1.0.1.min.js"></script> 
    <script type="text/javascript" src="/static_files/js/common/angular/angular-resource-1.0.1.min.js"></script> 
    <script type="text/javascript" src="/static_files/js/section/main-nav-controller.js"></script> 

    <script type="text/javascript"> 
    (function() { 
     var jasmineEnv = jasmine.getEnv(); 
     jasmineEnv.updateInterval = 1000; 

     var htmlReporter = new jasmine.HtmlReporter(); 

     jasmineEnv.addReporter(htmlReporter); 

     jasmineEnv.specFilter = function(spec) { 
     return htmlReporter.specFilter(spec); 
     }; 

     var currentWindowOnload = window.onload; 

     window.onload = function() { 
     if (currentWindowOnload) { 
      currentWindowOnload(); 
     } 
     execJasmine(); 
     }; 

     function execJasmine() { 
     jasmineEnv.execute(); 
     } 

    })(); 
    </script> 

</head> 

<body> 
</body> 
</html> 

Che cosa sto facendo di sbagliato? Non sono in grado di capire come dovrebbe funzionare questa cosa :)

risposta

57

Il problema principale con il codice di test è che tenta di creare l'istanza di un controller "a mano" utilizzando il nuovo operatore. Quando lo fa, AngularJS non ha alcuna possibilità di iniettare dipendenze. Che cosa si dovrebbe fare è quello di permettere AngularJS iniettare le dipendenze:

var $scope, ctrl; 

//you need to inject dependencies first 
beforeEach(inject(function($rootScope) { 
    $scope = $rootScope.$new();   
})); 

it('Should initialize value to Loading', inject(function($controller) { 
    ctrl = $controller('MainNavController', { 
     $scope: $scope 
    }); 
    expect($scope.wksp_name).toBe('Loading...'); 
})); 

ecco il link a un jsFiddle completo: http://jsfiddle.net/pkozlowski_opensource/7a7KR/3/

ci sono 2 cose da notare nell'esempio di cui sopra:

  1. È possibile utilizzare il metodo inject() dal modulo ngMock per iniettare le dipendenze: https://docs.angularjs.org/api/ngMock/function/angular.mock.inject
  2. Per creare un'istanza del controller (che supporti l'integrazione delle dipendenze) si utilizzerà $ controll servizio di ER: http://docs.angularjs.org/api/ng.$controller

Come ultima osservazione: vorrei consigliare nominare i controllori che iniziano con una lettera maiuscola - in questo modo noi non li confondono con i nomi delle variabili.

3

Sono d'accordo con la risposta di pkozowski, ma per rispondere alla tua domanda in modo più diretto, è necessario spegnere '$ sulla'

Il tuo esempio sarebbe passata se il vostro $ portata sembrava:

$scope = { 
    $on: function() {} 
} 
+1

o utilizzare una spia Jasmine –

16

Grande rispondi @ pkozlowski.opensource. Per elaborare un po 'di più ... A volte potrebbe essere anche utile affermare che $scope.$on è stato davvero chiamato dal controller. In questo caso si può spiare $scope.$on come sottolineato di seguito:

beforeEach(inject(function($rootScope) { 
    $scope = $rootScope.$new();   
    spyOn($scope, '$on').andCallThrough(); 
})); 

E poi si può affermare che $on è stato chiamato con il tuo nome e il alcune funzioni come argomenti:

it('Should bind to "broadCastWkspNameEvent"', inject(function($controller) { 
    ctrl = $controller('MainNavController', { 
     $scope: $scope 
    }); 
    expect($scope.$on).toHaveBeenCalledWith('broadCastWkspNameEvent', jasmine.any(Function)); 
})); 
Problemi correlati