使用服务测试控制器
Testing controllers with services
我是 angular 和单元测试的新手。
我有一个应用程序模块 MyApp
包括所有其他模块都需要的基本服务和服务,例如日志记录服务 loggingService
我还有一个模块用于处理关于地图和地理定位的所有内容,名为 MapModule
,我还有一个用于应用程序逻辑的主模块,名为 MainModule
MainModule
包含一个我想测试的控制器:messageSendCtrl
控制器有一些依赖性,比如来自 MapModule
.
的服务
并且:MainModule
和 MapModule
依赖于 MyApp
,因为到处都需要 loggingService
。
代码看起来像这样(伪代码):
MyApp
var MyApp = angular
.module('MyApp', ['ngRoute','MainModule','MapModule']);
MyApp.service('loggingService', function (one, two) {
[..] /*logging data somewhere for debugging application*/
});
主模块
var MainModule = angular
.module('MainModule', []);
MainModule.controller('messageSendCtrl',
function($scope,$http, $location, locationService, loggingService) {
[...]
});
MapModule
var MapModule = angular
.module('MapModule', ['uiGmapgoogle-maps']);
MapModule.service('locationService', function (loggingService) {
[...]
我喜欢测试的是MainModule
中的messageSendCtrl
。 (可能)我能够将定位服务注入测试环境。但是注入 locationService
没有成功。
可能是因为 locationService
也使用了 loggingService
.
运行 测试结果在
Error: [$injector:unpr] Unknown provider: loggingServiceProvider <- loggingService <- locationService
我的测试是这样的:
describe('saving a document', function() {
beforeEach(module('MainModule'));
beforeEach(module('MyApp'));
beforeEach(module('MapModule'));
describe ('messageSendCtrl', function () {
var scope,ctrl,locationService,loggingService;
beforeEach(inject(function($rootScope, $controller,_locationService_,_loggingService_) {
scope = $rootScope.$new();
ctrl = $controller('messageSendCtrl',
{$scope: scope,
locationService: _locationService_,
loggingService : _loggingService_ });
}));
it('should actual not saved', function(){
expect(scope.result).to.equal('unsaved');
});
})
});
那么我可以解决谁的依赖关系呢?还是我的应用程序存在设计问题?
事情有很多,让我们一一检查:
- 在你的测试中,你不需要加载你所有的模块,只加载你想要测试的那个模块,你的 ctrl 在你的 MainModule 中,所以只使用
beforeEach(module('MainModule'));
- 每个模块都应声明其依赖项,因此您的 MainModule 声明应如下所示:
var MainModule = angular.module('MainModule', ['MyApp']);
因为 MainModule 中的一个控制器依赖于另一个模块 (MyApp) 中的服务
- 测试一个模块是否只做一件事会更容易,因此如果您有日志记录服务,请为此创建一个日志记录服务模块,并将该模块包含在您要使用日志记录的位置。
所以不要让模块负责几个不同的事情,因为如果其他模块需要日志记录,该模块将获得您的 "godmodule" 包含的所有其他服务,这使得测试和查找错误变得困难。
我是 angular 和单元测试的新手。
我有一个应用程序模块 MyApp
包括所有其他模块都需要的基本服务和服务,例如日志记录服务 loggingService
我还有一个模块用于处理关于地图和地理定位的所有内容,名为 MapModule
,我还有一个用于应用程序逻辑的主模块,名为 MainModule
MainModule
包含一个我想测试的控制器:messageSendCtrl
控制器有一些依赖性,比如来自 MapModule
.
并且:MainModule
和 MapModule
依赖于 MyApp
,因为到处都需要 loggingService
。
代码看起来像这样(伪代码):
MyApp
var MyApp = angular
.module('MyApp', ['ngRoute','MainModule','MapModule']);
MyApp.service('loggingService', function (one, two) {
[..] /*logging data somewhere for debugging application*/
});
主模块
var MainModule = angular
.module('MainModule', []);
MainModule.controller('messageSendCtrl',
function($scope,$http, $location, locationService, loggingService) {
[...]
});
MapModule
var MapModule = angular
.module('MapModule', ['uiGmapgoogle-maps']);
MapModule.service('locationService', function (loggingService) {
[...]
我喜欢测试的是MainModule
中的messageSendCtrl
。 (可能)我能够将定位服务注入测试环境。但是注入 locationService
没有成功。
可能是因为 locationService
也使用了 loggingService
.
运行 测试结果在
Error: [$injector:unpr] Unknown provider: loggingServiceProvider <- loggingService <- locationService
我的测试是这样的:
describe('saving a document', function() {
beforeEach(module('MainModule'));
beforeEach(module('MyApp'));
beforeEach(module('MapModule'));
describe ('messageSendCtrl', function () {
var scope,ctrl,locationService,loggingService;
beforeEach(inject(function($rootScope, $controller,_locationService_,_loggingService_) {
scope = $rootScope.$new();
ctrl = $controller('messageSendCtrl',
{$scope: scope,
locationService: _locationService_,
loggingService : _loggingService_ });
}));
it('should actual not saved', function(){
expect(scope.result).to.equal('unsaved');
});
})
});
那么我可以解决谁的依赖关系呢?还是我的应用程序存在设计问题?
事情有很多,让我们一一检查:
- 在你的测试中,你不需要加载你所有的模块,只加载你想要测试的那个模块,你的 ctrl 在你的 MainModule 中,所以只使用
beforeEach(module('MainModule'));
- 每个模块都应声明其依赖项,因此您的 MainModule 声明应如下所示:
var MainModule = angular.module('MainModule', ['MyApp']);
因为 MainModule 中的一个控制器依赖于另一个模块 (MyApp) 中的服务 - 测试一个模块是否只做一件事会更容易,因此如果您有日志记录服务,请为此创建一个日志记录服务模块,并将该模块包含在您要使用日志记录的位置。 所以不要让模块负责几个不同的事情,因为如果其他模块需要日志记录,该模块将获得您的 "godmodule" 包含的所有其他服务,这使得测试和查找错误变得困难。