场景非常简单,我正在尝试测试服务A,这取决于服务B,所以我决定在注入服务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');
});
});
});
答案 0 :(得分:10)
您的服务注入应该在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
答案 1 :(得分:0)
使用间谍而不是模块覆盖服务,然后,当您测试(单元测试)服务A时,您只测试服务A,这意味着您可以模拟(间谍)服务B并假设您有服务测试B并且正在工作。
单元测试:
describe('My app services', function(){
beforeEach(module('MyApp.services'));
describe('service A', function(){
var serviceA, serviceB;
inject(function(_serviceA_, _serviceB_){
serviceA = _serviceA_;
serviceB = _serviceB_;
});
it('should work', function(){
spyOn(serviceB, 'greeting').and.returnValue('TEST');
var words = serviceA.greeting();
expect(words).toBe(I say: TEST');
});
});
describe('service B'. function(){
var serviceB;
inject(function(_serviceB_){
serviceB = _serviceB_;
});
it('should work', function(){
var words = serviceB.greeting();
expect(words).toBe('hello');
});
});
});