Jasmine/AngularJS: 在单元测试中向服务注入依赖服务?
Jasmine/AngularJS: Inject dependent service to service in unit test?
我有 angular 个模块:
var app = angular.module("SearchUI",[]);
其中,我有一个服务 "configService",它维护着一堆配置参数:
app.provider("configService",function(){
//stuff here
})
我在 configService fineL运行 中有 jasmine 单元测试
describe('configService',function(){
var configService,$httpBackend;
beforeEach(module('SearchUI'));
beforeEach(inject(function(_configService_,$injector){
configService = _configService_;
$httpBackend = $injector.get("$httpBackend");
}));
it('should have default values for configService', function(){
expect(configService.getDefaultSearch()).toEqual(['abstract','title','keyword','keywordplus'
]);
});
//other stuff
所有测试都顺利通过。
但是,我不明白如何在另一个服务中维护该注入:
即在我的申请中:
app.service("SearchService",function($http,$log,configService,$q){
//stuff
search_params = configService.getDefaultSearch();
})
我的规格:
describe('SearchService',function(){
var searchService,configService;
beforeEach(module('SearchUI'));
beforeEach(inject(function(_configService_,_SearchService_){
configService = _configService_;
searchService = _SearchService_;
}));
it('SearchService should return results', function(){
var waiting = searchService.SimpleSearch("card","wos",0);
//other stuff
规范失败,因为在 simplesearch 函数中需要这样:
search_params = configService.getDefaultSearch(); //get the default search parameters
我的问题是,如何将所需的服务注入到另一个服务中?
服务只是 JavaScript classes,您可以创建它们的实例而无需使用 angular 的注入机制来促进依赖注入。相反,您可以简单地自己创建一个 class 的新实例,同时提供所需的参数。
当前您正在通过内联函数创建服务:
app.service("SearchService",function($http,$log,configService,$q){...
而不是做一个小的调整,将服务的声明从它注入到 angular 模块中分离出来。这样做将允许您从测试中获得对服务 class.
的访问权限
function SearchService($http, configService){...
app.service("SearchService", SearchService);
从您的测试套件中,您可以在 beforeEach 预处理器中准备注射剂:
describe('configService',function(){
var configService, httpBackend;
beforeEach(module('SearchUI'));
beforeEach(inject(function($httpBackend){
httpBackend = "$httpBackend";
configService = jasmine.createSpyObj('configService', ['getDefaultSearch']);
}));
/* helper method that I create to only have one place where the service is created
If I add a new param/dependency then I only have to change the construction once */
function createService(){
return new SearchService(httpBackend, configService);
}
});
采用这种测试方法(手动控制依赖项注入而不是依赖 angular 的实现)的主要原因是为了完全控制并真正隔离我要测试的项目。
configService 和 SearchService 在模块 app 中初始化,但不在模块 SearchUI 中。将 "beforeEach(module('SearchUI'));" 替换为 "beforeEach(module('myapp'));"
我有 angular 个模块:
var app = angular.module("SearchUI",[]);
其中,我有一个服务 "configService",它维护着一堆配置参数:
app.provider("configService",function(){
//stuff here
})
我在 configService fineL运行 中有 jasmine 单元测试
describe('configService',function(){
var configService,$httpBackend;
beforeEach(module('SearchUI'));
beforeEach(inject(function(_configService_,$injector){
configService = _configService_;
$httpBackend = $injector.get("$httpBackend");
}));
it('should have default values for configService', function(){
expect(configService.getDefaultSearch()).toEqual(['abstract','title','keyword','keywordplus'
]);
});
//other stuff
所有测试都顺利通过。
但是,我不明白如何在另一个服务中维护该注入:
即在我的申请中:
app.service("SearchService",function($http,$log,configService,$q){
//stuff
search_params = configService.getDefaultSearch();
})
我的规格:
describe('SearchService',function(){
var searchService,configService;
beforeEach(module('SearchUI'));
beforeEach(inject(function(_configService_,_SearchService_){
configService = _configService_;
searchService = _SearchService_;
}));
it('SearchService should return results', function(){
var waiting = searchService.SimpleSearch("card","wos",0);
//other stuff
规范失败,因为在 simplesearch 函数中需要这样:
search_params = configService.getDefaultSearch(); //get the default search parameters
我的问题是,如何将所需的服务注入到另一个服务中?
服务只是 JavaScript classes,您可以创建它们的实例而无需使用 angular 的注入机制来促进依赖注入。相反,您可以简单地自己创建一个 class 的新实例,同时提供所需的参数。
当前您正在通过内联函数创建服务:
app.service("SearchService",function($http,$log,configService,$q){...
而不是做一个小的调整,将服务的声明从它注入到 angular 模块中分离出来。这样做将允许您从测试中获得对服务 class.
的访问权限function SearchService($http, configService){...
app.service("SearchService", SearchService);
从您的测试套件中,您可以在 beforeEach 预处理器中准备注射剂:
describe('configService',function(){
var configService, httpBackend;
beforeEach(module('SearchUI'));
beforeEach(inject(function($httpBackend){
httpBackend = "$httpBackend";
configService = jasmine.createSpyObj('configService', ['getDefaultSearch']);
}));
/* helper method that I create to only have one place where the service is created
If I add a new param/dependency then I only have to change the construction once */
function createService(){
return new SearchService(httpBackend, configService);
}
});
采用这种测试方法(手动控制依赖项注入而不是依赖 angular 的实现)的主要原因是为了完全控制并真正隔离我要测试的项目。
configService 和 SearchService 在模块 app 中初始化,但不在模块 SearchUI 中。将 "beforeEach(module('SearchUI'));" 替换为 "beforeEach(module('myapp'));"