Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modifying $scope Values for Angular Controller Unit Testing

All,

I have a unit test suite for a AngularJS controller that follows the pattern beforeEach():

var ResourcesCtrl,
    scope, rootScope, loc, ctrl;

  // Initialize the controller and a mock scope
  beforeEach(inject(function ($controller, $location) {
    scope = {};
    rootScope = {};
    loc = $location;
    ctrl = $controller;
    scope.instanceName = 'TestInstance';


    ResourcesCtrl = $controller('ResourcesCtrl', {
      $scope: scope,
      $rootScope: rootScope,
      $location: loc
    });
  }));

Then a bunch of it() blocks with assertions/expect that all work as expected.

Now what I need to do, in just one of the test cases I'm adding, is change the value of scope.instanceName; however, it appears that even if I change its value inside the it() test case, that's not reflected in the scope of the controller. I have tried instantiating the controller with a new scope inside the test case, but that hasn't worked either.

So my question is the following: how can I change/override variables that were passed to the controller in the beforeEach() setup?

like image 960
rdodev Avatar asked Apr 05 '14 02:04

rdodev


2 Answers

The problem here is that the call to $controller occurs in the beforeEach using whatever scope variables are available to it at that time. You want to be able to change the scope variable before the controller is called. One option is to use an init function which is called in each spec so that you can control exactly when the controller gets called:

beforeEach(inject(function ($controller, $location) {
  scope = {};
  rootScope = {};
  loc = $location;
  ctrl = $controller;
  scope.instanceName = 'TestInstance';

  this.init = function() {
    ResourcesCtrl = $controller('ResourcesCtrl', {
      $scope: scope,
      $rootScope: rootScope,
      $location: loc
    });
  }
}));

...

it("should do something", function() {
  scope.instanceName = "NewName";
  this.init();
  ...
});

Note that this means that this.init must be called in every spec in the file.

like image 176
alexsanford1 Avatar answered Nov 06 '22 06:11

alexsanford1


in your beforeEach add $rootScope to the parameter list and assign the following variables like this

scope = $rootScope.$new();
rootScope = $rootScope;

since they come from angular's $rootScope you can call $apply() if needed.

like image 45
Brocco Avatar answered Nov 06 '22 06:11

Brocco