角度应用程序初始化后激活$ httpMock

角度应用程序初始化后激活$ httpMock

问题描述:

我希望能够打开和关闭我的angularJS应用程序中的$ httpBackend模拟。

这意味着我想要注入$ httpBackend /懒惰/按需。 能够打开和关闭它也是很好的。

例如为从CMS预览的AngularJS应用程序提供输入数据。

下面的代码只有在将ngMockE2E移动到普通的依赖项时才起作用,并且将$ httpBackend注入我的工厂的标准方式。

代码设置UPP $ httpBackend从一个配置文件中的所有呼叫,然后回应所有的人......

const registerCalls =() => { 
    const injectormock = angular.injector(['ngMockE2E']); //lazy load not working as expected 
    const $httpBackend = injectormock.get('$httpBackend'); //lazy load not working as expected. 
    //Pass through for resources: 
    $httpBackend.whenGET(/.*.html/).passThrough(); 
    $httpBackend.whenGET(/.*.json/).passThrough(); 
    //API calls should be mocked: 
    const apiCalls = {}; 
    for (var call in apiConfig) { 
     if ({}.hasOwnProperty.call(apiConfig, call)) { 
      const callConfig = apiConfig[call]; 
      const url = angular.isDefined(callConfig.regex) ? callConfig.regex : callConfig.url(); 
      if (callConfig.method === 'GET') { 
       apiCalls[call] = $httpBackend.whenGET(url); 
      } else if (callConfig.method === 'POST') { 
       apiCalls[call] = $httpBackend.whenPOST(url); 
      } 
     } 
    } 
    return apiCalls; 

} 

const success = function() { 
    const apiCalls = registerCalls(); 
    for (var call in apiConfig) { 
     let response = {}; 
     if (angular.isDefined(apiConfig[call].response)) { 
      response = apiConfig[call].response(); 
     } 
     apiCalls[call].respond(200, response); 
    } 
}; 

我怎样才能设置了$ httpBackend,以便它可以被激活/停用而AngularJS应用程序正在运行?

角度服务是在第一次注入时被懒惰地实例化的单例。如果在应用程序引导时执行$httpBackend的注入(通常在使用$http的情况下),则无法模拟服务。

通过angular.injector获得E2E $httpBackend版本是显而易见的,但却是错误的做法。这将导致拥有使用自己的核心服务单例的新注入器实例($browser等)。

干净的方法是通过全球angular.mock.e2e,如this example所示。它将可用once angular-mocks.js is loaded。重点是装饰$httpBackend(这是一个函数)来包装原始和E2E实现并有条件地使用它们。

这是可以做到这样的:

angular.module('mockableHttp', []) 
.decorator('$httpBackend', function ($injector, $delegate) { 
    var $httpBackendOriginal = $delegate; 
    var $httpBackendE2E = $injector.invoke(angular.mock.e2e.$httpBackendDecorator, null, { 
    $delegate: $delegate 
    }); 

    function $httpBackend() { 
    var $httpBackendImplementation = $httpBackend.isMocking 
     ? $httpBackendE2E 
     : $httpBackendOriginal; 

    return $httpBackendImplementation.apply(this, arguments); 
    } 

    return Object.assign($httpBackend, $httpBackendE2E, { 
    enableMocking: function() { 
     $httpBackend.isMocking = true; 
    }, 
    disableMocking: function() { 
     $httpBackend.isMocking = false; 
    } 
    }); 
}); 

mockableHttp在应用程序模块被装载(可完全排除在生产)和HTTP嘲笑与$httpBackend.enableMocking()激活。

+0

非常好的答案,模式完美无缺 –

+0

很高兴为你工作。 – estus