4

I have the following component:

angular.module('foo')
    .component('searchInput', {
        bindings: {
            text: "<query"
        },
        templateUrl: 'components/searchInput/searchInput.html',
        controller: 'SearchInputCtrl'
    });

For the following to pass:

expect(component.text).toBe('bar');

I have to use the following code:

    var component = $componentController('searchInput',
        {$scope: {}},
        {
            text: 'bar'
        }
    );

However, I want to test that the value being bound to 'text' is being sourced from 'query'. This does not work:

    var component = $componentController('searchInput',
        {$scope: {}},
        {
            query: 'bar'
        }
    );
Daniel Smith
  • 553
  • 1
  • 6
  • 12

1 Answers1

7

You can test this sort of thing by compiling the component. e.g.

inject(function($compile, $rootScope) {
    var parentScope = $rootScope.$new();
    parentScope.myVar = 'test';

    var element = angular.element('<search-input query="myVar"></search-input>');

    var compiledElement = $compile(element)(parentScope);
    parentScope.$digest();

    var scope = compiledElement.isolateScope();

    expect(scope.$ctrl.text).toBe('test');
});
rob
  • 17,995
  • 12
  • 69
  • 94
  • that crossed my mind but I want something more in line with what the Angular developer guide suggests: $componentController -- it's easy and you avoid DOM and thus the extra steps of compiling and digesting. – Daniel Smith Apr 05 '16 at 17:06
  • The more I've pondered this and looked at the Angular source, as @rob pointed out, working with DOM is the only way. Since components are syntactic sugar for directives, I should have the same mindset/expectations when testing either of them. When testing an (explicit) directive's controller via $controller I am fine specifying the name of the target binding; the same should be true with testing a component's controller via $componentController. When testing the source attribute for a directive I use DOM and check isolateScope(); the same should be true with component source attributes. – Daniel Smith Apr 06 '16 at 17:20
  • I was having similar problem, when I passed a variable defined in binding like: `` it didn't work, but when I assigned the same thing in a scope variable and passed like: `` it worked not sure why? – Pawan Sep 26 '16 at 11:27
  • @Pawan if `binding-var` uses a two way binding then you'd have to pass a literal string in like `` – rob Sep 26 '16 at 15:39
  • @rob I tried again but passing the string value directly doesn't set the binding variable in the component. It gets set only when I pass it through a variable on the scope. – Pawan Sep 27 '16 at 11:19