I'm using jasmine to test my controllers, which I wrote in TypeScript. My unit tests are in plain javascript. I'm getting an error when I test my controller, where I want to inject a mock service.
This is how my test looks:
'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);
});
});
My app.ts:
module game {
'use strict';
var busybee = angular.module('busybee', []);
busybee.controller('configCtrl', ConfigCtrl);
busybee.service('configService', ConfigService);
...
...
}
and my TypeScript controller:
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
}
}
}
When running karma, I get the following error:
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)
It seems, there's a problem injecting the configService
, but I don't have an idea why.
EDIT: added a jsfiddle http://jsfiddle.net/Q552U/6/
UPDATE: It seems it was a problem for jasmine having the compiled javascript of the TypeScript classes in different files. Compiling the TypeScript files to a single .js file (tsc --out dest.js source.ts
), does it for me.
Try get the service using $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});
}));
Link to Demo.
Nice answer from zsong, but that code can be updated further by removing configService
from angular.mock.inject()
as it is not necessary.
Another possibility is to write your test in TypeScript (and use Jasmine type definitions), which is a cleaner way to do it. In that case, your test will look like this:
/// <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);
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With