Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to unit test spy on $emit in a directive?

How do I check if $emit has been called in an unit test of a directive?

My directive is fairly simple (for the purpose of illustration):

angular.module('plunker', [])
.directive('uiList', [function () { 
    return {
        scope: {
            lengthModel: '=uiList',
        },
        link: function (scope, elm, attrs) {
            scope.$watch('lengthModel', function (newVal) {
                        scope.$emit('yolo');
            });
        }
    }
}])

so every time the attribute uiList changes, it will emit the event.

And I have unit test code as follows:

describe('Testing $emit in directive', function() {
  var scope;
  var element;


  //you need to indicate your module in a test
    beforeEach(function () {
        module('plunker');
        inject(function ($rootScope, $compile) {
            scope = $rootScope.$new();
            scope.row= 1;
            spyOn(scope,'$emit');
        element = angular.element('<ul id="rows" ui-list="row">');
        $compile(element)(scope);
        });
    });

  it('should emit', function() {

    scope.$digest();
    scope.row = 2;
    scope.$digest();
    expect(scope.$emit).toHaveBeenCalledWith("yolo");
  });
});

This would always give me error stating that the scope.$emit has never been called. Is there something wrong with the scope? Can someone please help?

Plunker:http://plnkr.co/edit/AqhPwp?p=preview

like image 291
9blue Avatar asked Mar 19 '23 20:03

9blue


1 Answers

Your directive creates an isolated scope, which is calling $emit,so you need to spy on this one ;)

describe('Testing $emit in directive', function() {
  var scope;
  var element;
  var elementScope;

  beforeEach(module('plunker'));

  beforeEach(inject(function($rootScope, $compile) {
      scope = $rootScope.$new();
      scope.row = 1;
      element = angular.element('<ul id="rows" ui-list="row">');
      $compile(element)(scope);
      scope.$digest();
      elementScope = element.scope();
  }));

  it('should emit', function() {
    // arrange
    spyOn(elementScope, '$emit');

    // act
    scope.$apply(function() {
      scope.row = 2;
    });

    // assert
    expect(elementScope.$emit).toHaveBeenCalledWith("yolo");
  });
});

Fixed plunker here :)

like image 111
glepretre Avatar answered Mar 30 '23 10:03

glepretre