场景非常简单,我正在尝试测试依赖于服务 B 的服务 A,因此我决定在注入(inject)服务 A 之前通过覆盖它来模拟服务 B。但是,我也在测试不再有效的服务 B因为它被覆盖了。关于如何避免这种情况的任何想法?
应用代码。
angular.module('MyApp.services')
.factory('serviceB', function(){
return {
greeting: function(){ return 'hello'; }
}
})
.factory('serviceA', ['serviceB', function(serviceB){
return {
greeting: function(){
return 'I say: ' + serviceB.greeting();
}
});
单元测试:
describe('My app services', function(){
beforeEach(module('MyApp.services'));
describe('service A', function(){
// mock service B
angular.module('MyApp.services').factory('serviceB', function(){
return { greeting: function(){ return 'mocked B'; } }
});
var serviceA;
inject(function(_serviceA_){
serviceA = _serviceA_;
});
it('should work', function(){
var words = serviceA.greeting();
expect(words).toBe('I say: mocked B');
});
});
describe('service B'. function(){
var serviceB;
inject(function(_serviceB_){
serviceB = _serviceB_;
});
it('should work', function(){
var words = serviceB.greeting();
expect(words).toBe('hello');
});
});
});
最佳答案
您的服务注入(inject)可能应该在 beforeEach
中。或作为测试的一部分,否则我认为它们会在测试开始之前发生或根本不会发生,例如
beforeEach(inject(function(_serviceA_){
serviceA = _serviceA_;
}));
或者
it('should work', inject(function(serviceA){
var words = serviceA.greeting();
expect(words).toBe('I say: mocked B');
}));
为了解决您实际询问的问题,我建议您做以下两件事之一:
beforeEach(module(function($provide){
$provide.value('serviceB', {
greeting: function(){ return 'mocked B'; }
});
}));
见 plunker .
serviceB
在某个地方(只需要调用一次),将包含
serviceB
的模拟版本的新模块的定义放在angular.module('MyApp.services.mock', [])
.factory('serviceB', function(){
return { greeting: function(){ return 'mocked B'; } }
});
然后在您当前更改被测模块中的服务的地方,使用以下内容加载您的模块,并在顶部放置模拟。
beforeEach(module('MyApp.services.mock'));
见 plunker
关于AngularJS覆盖(模拟)单元测试服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20025402/