我正在测试服务1,这取决于另一个服务B.通常这样做的正确方法是在注入A之前使用$provide
对象。但是,我有两个约束:
问题是,到目前为止(我正在测试控制器),我能够从我的测试中访问服务B,我需要注入它。但是要在$provide
中模拟它,我需要在我的测试中访问它,这会产生问题,因为$provide
需要在任何inject()
之前使用。这是我的测试:
describe('viewsListService', function() {
var viewList,
queryDeferred,
mockViews,
$scope;
beforeEach(module('BoardMocks'));
beforeEach(module('Board'));
beforeEach(inject(function(mockViewsService) {
var query = {};
mockViewsService.init({}, query);
queryDeferred = query.deferred;
mockViews = mockViewsService.mock;
}));
beforeEach(function() {
angular.mock.module('Board', function ($provide) {
$provide.value('Views', mockViews);
});
});
beforeEach(inject(function(viewsListService, $rootScope) {
$scope = $rootScope.$new();
viewList = viewsListService;
// Initialisation of the viewsListService
viewList.init();
queryDeferred.resolve([1]);
$scope.$digest();
}));
describe('getAllViews', function() {
var allViews;
beforeEach(function() {
allViews = viewList.getAllViews();
});
it('should return all the views', function() {
expect(allViews.length).toBe(1);
});
});
});
这给了我一个Error: Injector already created, can not register a module!
,指向angular.mock.module调用。
我将我的模拟服务移动到另一个模块,认为它可能会解决问题,想知道注入器是否特定于模块,但它似乎不是(在第一个之后移动beforeEach(module('Board'));
inject()
无法解决问题。
你是否有任何想法让它工作,同时将模拟保存在外部文件中(我没有将其注册为Angular服务,但只是对于普通对象,如果它可以解决这个问题)。
答案 0 :(得分:3)
经过大量的回顾,我找到了Valentyn Shybanov的答案,解释了如何做到这一点。事实上这很简单。我会把它留给其他失去灵魂的人。
实际上在AngularJS中,依赖注入使用了最后的胜利'规则。因此,您可以在包含模块和依赖项之后立即在测试中定义服务,然后当您正在测试的服务A将使用DI请求服务B时,AngularJS将提供服务B的模拟版本。
所以,如果你想嘲笑"观看"服务。你创建了一个" BoardMocks"包含"视图"的模块服务。如果" BoardMocks"包含在" Board"之后,被嘲笑的"观看"测试期间将使用服务。
请在此处查看原始答案: Injecting dependent services when unit testing AngularJS services