3

Here is some Javascript that makes a call to jqLite's trigger inside the link function of an AngularJS directive.

angular.
  module('myApp').
  directive('myDirective',
    function($timeout) {
      return {
        link: function(scope) {

          scope.resetChosenElements = function() {
            $timeout(function() { 
                $('[chosen]').trigger('chosen:updated'); 
            }, 0);
          }

          scope.resetChosenElements();          

        }
      };
    }
  );

How can I write a test that checks that trigger is called when the directive is created without spying on $.trigger? (I don't want to spy on $.trigger because that catches all calls made to it, including those form other directives).

Is there a way to spy on the element argument that can be passed to link?

EDIT: My comment about spying on element seems to be causing confusion. I was only implying that if the solution required adding element to the arguments passed to link then that would be fine. However currently I have no use for it otherwise, which is why it's excluded from the argument list.

Trindaz
  • 17,029
  • 21
  • 82
  • 111

1 Answers1

1

Rathen that mock the trigger function you can spy the element's event function, as @Michael Benford said you are not using element in your code example, seems confusing considering your question any way:

This example is using ChaiJS as assertion tool and SinonJS as spies/stubs/mocks library You should add a spy on element customEvent

beforeEach(inject(function($rootScope, $compile, _$httpBackend_) {
    $scope = $rootScope.$new();
    compile = $compile;
    $httpBackend = _$httpBackend_;
    el = angular.element('<elementTemplateTag></elementTemplateTag>');
    compile(elm)($scope);
    spy = sinon.spy(el, "customEvent"); // Add spy on the event call
}));

afterEach(function(){
 el.customEvent.restore(); //clean spy calls
});

it('element.customEvent() called once', function() {

    el.trigger('customEvent');
    $timeout.flush(); // release all timeouts

    expect(el.customEvent.calledOnce()).to.be.true;
});

I hope this works for you.

Community
  • 1
  • 1
  • Thanks. I'm hesitant to resort to creating new event types every time I discover some limitation in AngularJS. IMO no new events should be fired in the normal course of assembling the UI of an application for which the only listener would be a unit test. – Trindaz May 03 '15 at 01:10
  • The "customEvent" was just an example, you can spy on "click", "change", etc, any event listener which is bound to the event that you need – Matias Fernandez Martinez May 03 '15 at 01:21