【问题标题】:Activate $httpMock after angular app has been initializedAngular 应用程序初始化后激活 $httpMock
【发布时间】:2017-04-11 01:34:59
【问题描述】:

我希望能够在我的 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 应用程序运行时激活/停用它?

【问题讨论】:

    标签: javascript angularjs httpbackend


    【解决方案1】:

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

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

    执行此操作的干净方法是通过angular.mock.e2e global,如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() 激活。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-26
      • 1970-01-01
      • 2020-01-27
      • 1970-01-01
      • 2013-04-09
      • 1970-01-01
      相关资源
      最近更新 更多