2013-08-27 17 views
7

Uso il jasmine per testare i miei controller, che ho scritto in TypeScript. I miei test unitari sono in chiaro javascript. Ricevo un errore quando eseguo il test del controller, dove desidero iniettare un servizio fittizio.Iniezione servizio simulato in AngularJS/Jasmine

Ecco come il mio test cerca:

'use strict'; 

describe('ConfigCtrl', function(){ 
    var scope, http, location, timeout, $httpBackend, service; 

    beforeEach(angular.mock.module('busybee')); 

    beforeEach(angular.mock.inject(function($rootScope, $http, $location, $timeout, configService, $controller){ 

     scope = $rootScope.$new(); 
     http = $http; 
     location = $location; 
     timeout = $timeout; 
     service = configService; 


     $controller('configCtrl', {$scope: scope, $http: http, $location: location, $timeout: timeout, configService: service}); 
    })); 

    it('should have text = "constructor"', function(){ 
     expect(true).toBe(true); 
    }); 
}); 

miei app.ts:

module game { 
    'use strict'; 

    var busybee = angular.module('busybee', []); 
    busybee.controller('configCtrl', ConfigCtrl); 

    busybee.service('configService', ConfigService); 
    ... 
    ... 

} 

e il mio controller dattiloscritto:

module game { 
    'use strict'; 

    export class ConfigCtrl { 

     static $inject: string[] = ['$scope', '$http', '$location', '$timeout', 'configService']; 

     constructor($scope: ng.IScope, $http: ng.IHttpService, $location: ng.ILocationService, 
      $timeout: ng.ITimeoutService, configService: game.ConfigService) { 
      //any code here 
     } 
    } 
} 

Quando si esegue il karma, ottengo il seguente errore:

Chrome 28.0.1500 (Linux) ConfigCtrl should have text = "constructor" FAILED 
     TypeError: Cannot read property 'prototype' of undefined 
      at Object.instantiate (/home/david/git/busybee2-client/js/libs/angular/angular.min.js:28:283) 
      at Object.<anonymous> (/home/david/git/busybee2-client/js/libs/angular/angular.min.js:28:494) 
      at Object.d [as invoke] (/home/david/git/busybee2-client/js/libs/angular/angular.min.js:28:174) 
      at /home/david/git/busybee2-client/js/libs/angular/angular.min.js:29:339 
      at c (/home/david/git/busybee2-client/js/libs/angular/angular.min.js:27:13) 
      at Object.d [as invoke] (/home/david/git/busybee2-client/js/libs/angular/angular.min.js:27:147) 
      at workFn (/home/david/git/busybee2-client/js/libs/angular/angular-mocks.js:1778:20) 
     Error: Declaration Location 
      at Object.window.jasmine.window.inject.angular.mock.inject [as inject] (/home/david/git/busybee2-client/js/libs/angular/angular-mocks.js:1764:25) 
      at null.<anonymous> (/home/david/git/busybee2-client/js/test/ConfigCtrlSpecs.js:9:29) 
      at /home/david/git/busybee2-client/js/test/ConfigCtrlSpecs.js:3:1 
Chrome 28.0.1500 (Linux): Executed 1 of 1 (1 FAILED) ERROR (0.329 secs/0.032 secs) 

Sembra, c'è un problema nell'iniettare il configService, ma non ho idea del perché.

EDIT: ha aggiunto un jsfiddle http://jsfiddle.net/Q552U/6/

UPDATE: Sembra che fosse un problema per il gelsomino avere il javascript compilato delle classi dattiloscritto in file diversi. Compilare i file TypeScript in un singolo file .js (tsc --out dest.js source.ts), lo fa per me.

+1

Puoi creare un violino del codice con i test in modo che tutti possano dare un'occhiata a questo? (Dal momento che non molte persone usano il TypeScript, il violino può aiutare a eseguire il debug.) – zsong

risposta

12

Provare a utilizzare il servizio utilizzando $injector.

beforeEach(angular.mock.inject(function($rootScope, $http, $location, $timeout, configService, $controller, $injector){ 
    scope = $rootScope.$new(); 
    http = $http; 
    location = $location; 
    timeout = $timeout; 
    service = $injector.get('configService'); //not sure the name, you may try 'ConfigService' as well. 

    $controller('configCtrl', {$scope: scope, $http: http, $location: location, $timeout: timeout, configService: service}); 
})); 

Collegamento a Demo.

+0

Grazie mille! – Johannes

+0

Link to Demo genera un 404 – Braulio

4

Bella risposta da zsong, ma il codice può essere aggiornato ulteriormente rimuovendo configService da angular.mock.inject() poiché non è necessario.

Un'altra possibilità è scrivere il test in TypeScript (e utilizzare le definizioni di tipo Jasmine), che è un modo più semplice per farlo. In questo caso, il tuo test sarà simile a questo:

/// <reference path="typings/jasmine/jasmine.d.ts" /> 

describe('ConfigCtrl',() => { 
    var configCtrl, scope, http, location, timeout, configServiceFake; 

    beforeEach(angular.mock.module('busybee')); 

    beforeEach(angular.mock.inject(($rootScope, $http, $location, $timeout, configService) => { 
     scope = $rootScope.$new(); 
     http = $http; 
     location = $location; 
     timeout = $timeout; 
     configServiceFake = configService; 

     configCtrl = new game.ConfigCtrl(scope, http, location, timeout, configServiceFake); 
    })); 

    it('should have text = "constructor"',() => { 
     expect(true).toBe(true); 
    }); 
}); 
Problemi correlati