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

时间:2017-04-10 14:28:44

标签: javascript angularjs httpbackend

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

1 个答案:

答案 0 :(得分:1)

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

通过$httpBackend获取E2E angular.injector版本是显而易见的,但却是错误的方法。这将导致使用其自己的核心服务单例($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;
    }
  });
});

在app模块中加载mockableHttp(可以在生产中完全排除),并使用$httpBackend.enableMocking()激活HTTP模拟。