在多个Angular模块中使用protractor-http-mock

时间:2016-09-29 12:37:27

标签: angularjs protractor angularjs-e2e

我有一个Angular应用程序需要在实际启动之前从后端加载配置。我需要为应用程序编写E2E测试,以便它独立于后端。我为此目的使用了protractor-http-mock。最初有一个angular-deferred-bootstrap模块管理配置依赖,但它在我的portal模块完全自举之前运行,因此量角器在此阶段没有注入httpMock模块。我的下一步决定是将bootstrap流程转换为单独的模块portalBootstrap

angular
    .module('portalBootstrap', [])
    .run(['$http', '$q', '$log', '$location', ($http, $q, $log, $location) => {
        bootstrap($http, $q, $log, $location).then(config => {
            angular.module('portal').constant('conf', config);
            var injector = angular.bootstrap(document, ['portal']);
        });
    }]);

angular.element(document).ready(() => {
    var bootstrapElement = document.getElementById('bootstrap');
    var injector = angular.bootstrap(bootstrapElement, ['portalBootstrap']);
});

据我了解,模拟模块注入如下:

  1. addMockModule被调用,httpMock进入量角器的内部模拟模块注册表
  2. browser.get被调用
  3. 量角器等待角度可用并暂停其引导程序
  4. 量角器将httpMock注入selenium
  5. 量角器调用angular.resumeBootstrap将所有模拟模块名称作为参数,因此使用它们创建模块注入器。
  6. 此时httpMock可以访问portalBootstrap$http请求被模拟。

    问题是现在第二个模块(portal)没有收到httpMock模块的副本,因为browser.getportalBootstrap时没有被执行,这是非常明显的{1}}收到其配置并转到portal

    protractor是否可以将httpMock注入两个模块?或者可能会建议一些引导架构更改?

    应避免使用angular.module('portal', ['httpMock'])之类的任何硬编码,因为非测试环境中不存在httpMock

1 个答案:

答案 0 :(得分:0)

尝试仅引导portal并手动注入portalBootstrap,如下所示:

angular
    .module('portalBootstrap', [])
    .run(['$http', '$q', '$log', '$location', ($http, $q, $log, $location) => {
        bootstrap($http, $q, $log, $location).then(config => {
            angular.module('portal').constant('conf', config);
            var injector = angular.bootstrap(document, ['portal']);
        });
    }]);

angular.element(document).ready(() => {
    var injector = angular.injector(['portalBootstrap']);
});

如果您需要拥有$rootElement或角度服务,例如$location,您可以伪造一个$rootElement,如下所示:

angular
    .module('portalBootstrap', [])
    .run(['$http', '$q', '$log', '$location', ($http, $q, $log, $location) => {
        bootstrap($http, $q, $log, $location).then(config => {
            angular.module('portal').constant('conf', config);
            var injector = angular.bootstrap(document, ['portal']);
        });
    }]);

angular.element(document).ready(() => {
    var bootstrapElement = document.getElementById('bootstrap');
    var ngBootstrapElement = angular.element(bootstrapElement);
    angular.module('portalBootstrap').constant('$rootElement', ngBootstrapElement);
    var injector = angular.injector(['portalBootstrap']);
});