Accessing the compiled template in unit tests

Most Angular tutorials talk about using end-to-end tests with Protractor to check if a compiled template exited as expected. I am wondering if it is possible to do this with unit tests.

Most of the tutorials that talk about referencing HTML code in unit tests describe how to compile your own written code in a test, for example, to make sure the directive is being accessed correctly:

describe('some function', function () {
  it('should do something', inject(function ($compile, $rootScope) {
    var element = $compile('<div id = "foo" ng-hide = "somecondition">Bar</div>')($Scope);
    $rootScope.digest();
    //Search for a given DOM element and perform some test here
  }));
});

      

But let's say I want to validate the code in the actual template file. For example, if I wanted to check if ng-hide was installed successfully. I want to be able to do something like:

describe('some function', function () {
  it('should do something', function () {
    //Get the div with ID 'foo' in the compiled template
    var elm = $('#foo');
    expect(elm.css('display')).toEqual('none');
  });
});

      

It doesn't work when I do this. elm

is set to some HTML / Javascript code, but not template code, but is elm.css('display')

returned as undefined.

Is there a way to unit test with Jasmine / Angular setup?

+3


source to share


2 answers


Load HTML templates in Angular $templateCache

with ng-html2js so that they are available in your tests.

Load your template into your tests:

var template = $templateCache.get('my/template.html');

      

Wrap the template in a jqLite / jQuery object to make it easier to use:

var element = angular.element(template);

      



Then you can select items in the template:

var fooEl = element.find('#foo');

      

For assertion, you don't want to check what is set in the element display: none

, checking for internal implementations ng-hide

. You can trust that the Angular team has their own tests that cover setting CSS properties. Instead, you want to validate the spelling of the template, so it is more appropriate to test for the existence of an attribute ng-hide

on an element, and that it is scoped with the correct scope to bind to:

expect(fooEl.attr('ng-hide')).toBe('isFooElHidden');

      

+6


source


In addition to @ user2943490's correct answer:



  • It is good practice to define a selection and not use $ rootScope var scope = $rootScope.$new(); var element = $compile(template)(scope);

  • in most cases, you want to check properties from the scope of the inner directive. You can define it in your beforeEach method like this and access it in all your tests: var isolatedScope = element.isolateScope(); expect(isolatedScope.property).toEqual(value);

+3


source







All Articles