AngularJS覆盖(模拟)单元测试服务

标签 angularjs

场景非常简单,我正在尝试测试依赖于服务 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');          
}));

为了解决您实际询问的问题,我建议您做以下两件事之一:
  • 覆盖注入(inject)器中的服务而不是模块
    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/

    相关文章:

    android - 无法加载资源:net::ERR_FILE_NOT_FOUND ionic 错误

    javascript - AngularJs 指令模板不起作用

    angularjs - Angular UI 网格 : filtering cross-column or cross-row

    javascript - Angular.js 将过滤器传递给指令双向 ('=' ) 属性

    javascript - 为 rootscope promise 提供 Angular 服务

    angularjs - 如何在 Angular.js 中使用 promises 并在查询字符串中使用 $resource?

    javascript - 如何绘制路径为 "d"属性的菱形?

    angularjs - 添加层级依赖的 TypeLite 生成

    javascript - Angularjs 不显示任何输出

    javascript - 当我在 Angular js 的 Post 请求中传递 session ID 时出现 404 错误