Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS, prevent init method on controller from launching during jasmine tests

I have a controller with a init() method launched on instantiation. It does a bunch of things which are useful for my app in a live environment, but that messes up with my unit-tests spies.

Is there a way to prevent its call when instantiating the controller in the unit-test environment ? Or maybe a way to have it called automatically in the webapp context without making an explicit call to init() at the end of the controller code ?

like image 375
mlarcher Avatar asked Feb 17 '13 13:02

mlarcher


1 Answers

It is a bit hard to provide precise guidance without seeing a live code example (this is why it is usually a good idea to provide a plunk that has a template for Jasmine tests) but it sounds like your init method executes some setup logic that should be different depending on the environment. If so the way to move forward would be to encapsulate this initialization logic into a dedicated service and mock this service during testing (this is exactly what @Joe Dyndale is suggesting).

Provided that your controller looks like follows:

app.controller('MainCtrl', function($scope) {
  $scope.init = function() {
    //something I really don't want to call during test
    console.log("I'm executing");
  };
});

It could be refactored to:

app.factory('InitService', function() {
  return {
    init = function() {
      //something I really don't want to call during test
      console.log("I'm executing");
    }
  };
});

app.controller('MainCtrl', function($scope, InitService) {
  InitService.init();
});

and then the test with mocking could look like so:

describe('Testing an initializing controller', function() {
  var $scope, ctrl;

  //you need to indicate your module in a test
  beforeEach(module('plunker'));
  beforeEach(module(function($provide){
    $provide.factory('InitService', function() {
      return {
        init: angular.noop
      };
    });
  }));
  beforeEach(inject(function($rootScope, $controller) {
    $scope = $rootScope.$new();
    ctrl = $controller('MainCtrl', {
      $scope: $scope
    });
  }));

  it('should test sth on a controller', function() {
    //
  });
});

Finally here is a live code in plunker

like image 121
pkozlowski.opensource Avatar answered Sep 29 '22 13:09

pkozlowski.opensource