Angular 1.5 unit testing component while ignoring child components Angular 1.5 unit testing component while ignoring child components angularjs angularjs

Angular 1.5 unit testing component while ignoring child components


Here is a very good explanation of how to test a component without rendering the whole tree under the current component.

What you want is called

shallow rendering (avoid rendering the whole template of the child component)

and Angular 1.5 doesn’t offer it out-of-the-box.

If you take a look at the link above, Wojciech Zawistowski shows how to use the helper below in order to achieve shallow rendering.

export function componentSpyOn(name) {  function componentSpy($provide) {    componentSpy.bindings = [];    $provide.decorator(name + 'Directive', ($delegate) => {      let component = $delegate[0];      component.template = '';      component.controller = class {        constructor() {          componentSpy.bindings.push(this);        }      };      return $delegate;    });  }  return componentSpy;}


You can do this by overriding your child component with $compileProvider.directive even though it is a component, because a component is a special kind of directive.

In your unit tests register a new component with the compiler with the same name as your child component but do not provide a controller and set the template to an empty string. This will result in a component without any logic/complexity:

beforeEach(module('app', function($compileProvider){    $compileProvider.directive('myComplexComponent', function (){        return {            priority: 9999,            terminal: true,            template: ''        };    });}));

So, the resulting html will be the most ideal for your outer component unit tests:

<span>John</span>    


There is a way to test it but the final result will be:

<span>John</span><ng-transclude></ng-transclude>

Component code:

  angular.module('app').component('myComponent', {  enter code herebindings: {    username: '<',  },  template: `    <span>{{ $ctrl.username }}</span>    <ng-transclude></ng-transclude>  `,  transclude: true, // Added property  controller: function () {}});

As you can see I deleted <my-complex-component>, and added <ng-transclude> instead.

That means that you can add your information from the outside and it will be injected at the location of ng-transclude.

For example this in your main html:

<my-component>    <my-complex-component></my-complex-component></my-component>

Will be in the DOM in the way that you wanted from the start:

<span>John</span><my-complex-component></my-complex-component>

After that your test should work.

I hope this answer is what you wanted and that it will help you.