Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to test function in controller scope executed by event

Tags:

function in controller:

angular.module('myApp').controller('MyController', function(){

   $scope.f = function($event){
      $event.preventDefault();
      //logic
      return data;
   }
})

describe('MyController', function(){
    'use strict';
    var MyController,
        $scope;

    beforeEach(module('myApp'));

    beforeEach($inject(function($rootScope, $controller){
       $scope = $rootScope.$new();
       MyController = $controller('MyController', {
          $scope: $scope
       })
    }));
})
it('should...', function(){
    //fire event and expect data
})

$scope.f function is used in directive, it can be executed by ng-click="f($event)"

what is right way for fire event in unit test?

like image 955
rossoneri Avatar asked Aug 31 '16 12:08

rossoneri


People also ask

How to do unit testing in Angular js?

Testing in AngularJS is achieved by using the karma framework, a framework which has been developed by Google itself. The karma framework is installed using the node package manager. The key modules which are required to be installed for basic testing are karma, karma-chrome-launcher ,karma-jasmine, and karma-cli.

Which component is used to inject and mock AngularJS service within the unit test?

AngularJS also provides the ngMock module, which provides mocking for your tests. This is used to inject and mock AngularJS services within unit tests.


1 Answers

Short Answer

You don't need to fire the event. You have access to the scope, which has the function you want to test. This means you just execute the function, then assert. It will look something like this:

it('should call preventDefault on the given event', function(){
  var testEvent = $.Event('someEvent');
  $scope.f(testEvent);
  expect(testEvent.isDefaultPrevented()).toBe(true);
});

See the following:

  • jQuery Event Object
  • event.isDefaultPrevented()

Full Spec

Also - your it block should be inside your describe block, so that it has access to the $scope field. It should look more like this:

describe('MyController', function(){
  'use strict';
  var MyController,
      $scope;

  beforeEach(module('myApp'));

  beforeEach($inject(function($rootScope, $controller){
    $scope = $rootScope.$new();
    MyController = $controller('MyController', {
      $scope: $scope
    })
  }));

  it('should call preventDefault on the given event', function(){
    var testEvent = $.Event('someEvent');
    $scope.f(testEvent);
    expect(testEvent.isDefaultPrevented()).toBe(true);
  });
})

A Note About Structure

Don't be afraid to use the describe blocks to structure your tests. Imagine you had another function on the $scope called f2, then you would probably want to partition your spec file up more like this:

describe('MyController', function(){
  'use strict';
  var MyController,
      $scope;

  beforeEach(module('myApp'));

  beforeEach($inject(function($rootScope, $controller){
    $scope = $rootScope.$new();
    MyController = $controller('MyController', {
      $scope: $scope
    })
  }));

  describe('$scope', function() {
    describe('.f()', function() {
      // tests related to only the .f() function
    });

    describe('.f2()', function() {
      // tests related to only the .f2() function
    });
  });
})

This has the benefit that when a test fails, the error message you see is constructed based on the hierarchy of describe blocks. So it would be something like:

MyController $scope .f() should call preventDefault on the given event

like image 162
Seth Flowers Avatar answered Sep 25 '22 16:09

Seth Flowers