在 Angular 1.5 中测试没有编译嵌套组件的组件



我目前面临一种情况,即我必须测试一个组件,该组件包含另一个具有自己的UT隔离的组件。像这样:

<parent-component>
    <div>
       <child-component form-data="formData"></child-component>
    </div>
</parent-component>

在测试用例之前,我编译传递范围参数的元素及其模板:

 beforeEach(inject((_$q_, _$rootScope_, $compile) => {
        $q = _$q_;
        $rootScope = _$rootScope_;
        $scope = $rootScope.$new();
        makeComponent = (scopeParam, template) => {
          const componentTemplate = template || defaultTemplate;
          const scope = _.merge($scope, scopeParam);
          element = $compile(angular.element(componentTemplate))(scope);
          scope.$apply();
        };
        makeController = (params, template) => {
          makeComponent(params, template);
          return element.controller(component.name);
        };
      }));

其中一个范围参数它引用formData,该将一个绑定传递给child-component并且每当更改时(实际上是$onInit parent-component(,都会触发child-component $onChanges,并且侦听此更改会导致调用一个方法,该方法分别从我在其 UT 中模拟的端点检索一些数据。

问题是,当UT的唯一目的是单独测试组件逻辑时,我想避免在parent-component上呈现此child-component并复制测试逻辑的需要。我怎么能只测试这个父组件并丢弃它上面的任何嵌套组件?

我用一个解决方案回答自己。这个想法是使用 decorators 来修改现有类的行为,而无需修改代码本身。了解更多:https://docs.angularjs.org/guide/decorators。我们唯一需要做的就是实例化我们的模拟模块并传递$provide并调用decorator方法,然后使用我们的组件名称调用然后同时传递"指令",其中包含组件/服务$delegate然后向提供程序注册。我们只需要设置一个自定义模板和控制器,在本例中为:emtpy 值,并返回它。简单地说,子组件将在其空控制器上生成一个空模板,我们可以专注于测试隔离的父组件。

beforeEach(angular.mock.module(module, ($provide) => {
 $provide.decorator('myComponent' + 'Directive', ($delegate) => {
   const comp = $delegate[0];
   comp.template = '';
   comp.controller = class {};
   return $delegate;
 });
});

最新更新