1

Following this question I'm using the following method to try to test whether ng-if tagged divs are displaying correctly using Karma, rather than Protractor:

var element;

beforeEach(inject(function ($rootScope, $templateCache, $compile) {
  scope = $rootScope.new();
  fooController.init(scope); //Some controller function that sets properties on the scope
                             //which are tested for in the template
  scope.$digest();
  var template = $templateCache.get('/my/template');  //Get the cached template
  var compiled = compile(template)(scope);            //Compile it

  element = angular.element(compiled);                //Wrap it with jQuery functions
}));

it('should do something', function () {
  var div = element.find('#someDiv'); //Get some div that should be affected by ng-if
  expect(div.html()).toBeUndefined(); //Expect the div not to be shown due to properties that
                                      //were set by fooController.init
});

My template has something like this:

<!-- scope.shown should be set to false by fooController.init -->
<div id = "someDiv" ng-if = "shown">Foo</div>

Here, I'm using expect(div.html()).toBeUndefined(); because ngIf (unlike ngShow and ngHide) removes the entire div from the DOM if the condition inside evaluates to false (ngShow and ngHide apply classes to the div to cause it not to be shown instead).

However, when I run this and print out the compiled variable, I find that the HTML of the ngIf div is ALWAYS taken away and replaced with a comment, regardless of the value of scope.shown.

Does the Angular compile function used by Karma not work the same way as it does when it's actually rendered by Angular itself in a browser? I ask because when I test it with a browser, it displays correctly, but when I try to unit test it, it outputs the wrong info. Maybe it's also because I'm using PhantomJS for headless testing, but Google Chrome to test it myself?

Community
  • 1
  • 1
A. Duff
  • 4,097
  • 7
  • 38
  • 69
  • Have you tried switching the browser the tests run on to Chrome and see if the behaviour is replicated? – AlvinJ Nov 24 '14 at 21:32
  • Haven't tried it because it's not an option. The project is large enough that we can't just change our testing suite like that. – A. Duff Nov 25 '14 at 23:07
  • Possible duplication http://stackoverflow.com/questions/24246811/testing-ng-if-using-compile – Adamy Jun 29 '15 at 00:55
  • If memory serves correctly, I don't think the `ng-if`ed element was the only one in the template. But this was more than eight months ago, so I could be wrong. – A. Duff Jun 29 '15 at 13:11

1 Answers1

-1

You need to evaluate shown in your template. Try creating a function that returns true or false. And then add this to your template.

ng-if = "GetShown([parameters]) === true"

So the function in your controller would be something like

$scope.GetShown = function([parameters]){
     return [evaluation]
};
Michael
  • 111
  • 1
  • 11
  • Unfortunately, that doesn't work, but thanks for the suggestion. – A. Duff Nov 25 '14 at 23:06
  • No problem, i'm sorry I couldnt be of more help. I think I should have posted as a comment rather than an answer. I'm newer to Stack overflow so I apologize. – Michael Dec 01 '14 at 19:20