我使用jasmine来测试我在TypeScript中编写的控制器。我的单元测试是用普通的javascript。 我在测试控制器时遇到错误,我想注入模拟服务。
这是我测试的样子:
'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);
});
});
我的app.ts:
module game {
'use strict';
var busybee = angular.module('busybee', []);
busybee.controller('configCtrl', ConfigCtrl);
busybee.service('configService', ConfigService);
...
...
}
和我的TypeScript控制器:
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
}
}
}
当运行业力时,我收到以下错误:
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)
看来,注入configService
会出现问题,但我不知道为什么会这样做。
编辑:添加了一个jsfiddle http://jsfiddle.net/Q552U/6/
UPDATE :对于jasmine来说,在不同的文件中编译了TypeScript类的javascript似乎是一个问题。将TypeScript文件编译为单个.js文件(tsc --out dest.js source.ts
),对我来说就是这样。
答案 0 :(得分:12)
尝试使用$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});
}));
链接到Demo。
答案 1 :(得分:4)
zsong的答案很好,但是可以通过从configService
删除angular.mock.inject()
来进一步更新该代码,因为这不是必需的。
另一种可能性是在TypeScript中编写测试(并使用Jasmine类型定义),这是一种更简洁的方法。在这种情况下,您的测试将如下所示:
/// <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);
});
});