I have a simple component below that I want to test that the ng-click event 
handler function is triggered. 
Currently to test the click event, I have to:

   1. compile the angular component element with a new scope 
   2. then get that element's isolate scope
   3. replace the isolate scope $ctrl with a new one that has a jasmine spy 
   in place of the click handler function 
   4. make my way through the compiled element and execute .click() on the 
   DOM element within my component that triggers the handler
   5. check that the spy was called
   
*Is there a better way to test this?*


*Since I'm using the 1.5 component, is it possible to add a spy via the 
$componentController's scope?*



*component:*

module.component('note', {
  bindings: {
    notepad: '='
  },
  template: [
    '<div ng-if="!$ctrl.notepad.note">',
      '<p ng-click="$ctrl.handleOnClick()"><i class="fa fa-plus"></i> Add a 
note</p>',
    '</div>',
    '<div ng-if="$ctrl.notepad.note">',
      '<p ng-click="$ctrl.handleOnClick()">',
        '<span ng-bind="$ctrl.notepad.note"></span>',
      '</p>',
    '</div>',
  ].join(''),
  controller: ['$modal', function($modal) {
    function handleOnClick() {
      // ... open a modal to handle entering the note ...
    }

    this.handleOnClick = handleOnClick;*  // <-- how can I test this 
function with $componentController*
  }]
});


If I create a controller in the tests via $componentController, I do not 
have access to handleOnClick, only the bindings, unless I use 

*testing:*

describe("note component", function(){
    // globals set up and used in each test scenario
    var component, scope, notepad, $componentController, element;

    beforeEach(module('app'));

    beforeEach(inject(function($rootScope, _$componentController_, 
$compile) {
        scope = $rootScope.$new();
        // this part creates a controller we can test
        $componentController = _$componentController_;
        notepad = {
            note: 'We have a note',
        };
        // this part for testing the component compiles correctly and 
create the DOM
        element = angular.element('<note note="notepad"></note>');
        element = $compile(element)(scope);
        scope.notepad = notepad;
        scope.$apply();
    }));

    it("should bind notepad to the controller scope", function() {
        component = $componentController('note', null, {notepad: notepad});
        expect(component.notepad).toBeDefined();
        expect(component.notepad.note).toBe('We have a note');
        expect(component.handleOnClick).toBeDefined();
    });

   
    *// Is it possible to use the $componentController to spy on the 
function in this test?*
    it('should open a modal to edit the note when clicked', function () {
        // arrange
        var isolate_scope = element.isolateScope();
        isolate_scope.$ctrl = {
            handleOnClick: jasmine.createSpy('callback'),
            notepad: notepad
        };
        isolate_scope.$apply();
        var divs = element.find('div');
        var p_tags = divs.find('p');
        // act
        p_tags.eq(0).click();
        // assert
        expect(isolate_scope.$ctrl.handleOnClick).toHaveBeenCalled();
    });
});

Thanks,
Aleck

-- 
You received this message because you are subscribed to the Google Groups 
"AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/angular.
For more options, visit https://groups.google.com/d/optout.

Reply via email to