【问题标题】:How to recreate AngularJS service for testing purposes?如何为测试目的重新创建 AngularJS 服务?
【发布时间】:2016-03-28 17:01:38
【问题描述】:

我想测试 myService 初始化,这可能因条件而异:

service('myService', function(internalService){
   if(internalService.param){ init1(); }
   else { init2(); }

   //...
});

我可以模拟internalService,但是如何重新创建myService?

【问题讨论】:

    标签: angularjs unit-testing angularjs-service


    【解决方案1】:

    服务在配置阶段后由注入器 (inject(...)) 实例化。要测试您的初始化,您需要做的就是在每个测试中进行不同的设置。也就是说,与其在beforeEach 块中实例化您的服务,不如在测试中进行。

    例如,您可以通过将internalService 模拟为具有param: true 来测试使用init1 实例化的副作用

    describe('Unit: myService', function() {
      it('should perform init1 if internalService.param', function() {
        var mockInternalService = {
          param: true,
        };
    
        // config phase (mocking)
        module('app', function($provide) {
          $provide.constant('internalService', mockInternalService);
        });
    
        inject(function($injector) {
          myService = $injector.get('myService');
    
          // assert side effects from init1();
        });
      });
    });
    

    要测试init2 的副作用,只需将internalService 模拟为param: false

      it('should perform init2 if !internalService.param', function() {
        var mockInternalService = {
          param: false,
        };
    
        // config phase (mocking)
        module('app', function($provide) {
          $provide.constant('internalService', mockInternalService);
        });
    
        inject(function($injector) {
          myService = $injector.get('myService');
    
          // assert side effects from init2();
        });
      });
    

    编辑:当然,如果您想对每个配置进行多次测试,您可以创建两个具有不同beforeEach 的describe 块。

      describe('Unit: myService', function() {
        var myService;
    
        describe('When instantiated with `init1`', function() {
          beforeEach(config(true));
          beforeEach(inject(injections));
    
          it('should do X');
        });
    
        describe('When instantiated with `init2`', function() {
          beforeEach(config(false));
          beforeEach(inject(injections));
    
          it('should do Y');
        });
    
        function config(param) {
           return function() { 
             var mockInternalService = {
               param: param,
             };
    
             // config phase (mocking)
             module('app', function($provide) {
               $provide.constant('internalService', mockInternalService);
             });
          };
        }
    
        function injections($injector) {
          myService = $injector.get('myService');
        }
      });
    

    【讨论】:

    • 这是否意味着我必须为每个“它”创建单独的模块定义?
    • 没有什么能阻止您为两种设置创建一个带有 beforeEach 的描述块。我会更新我的答案。
    • "a describe block with a beforeEach" - 是的,这就是我所做的。谢谢你的详细解答!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-23
    • 2022-01-11
    • 2014-02-26
    • 2011-05-15
    • 1970-01-01
    • 2019-02-18
    • 1970-01-01
    相关资源
    最近更新 更多