emersonthis
emersonthis

Reputation: 33348

Angular unit testing: how to test controller properties without scope

I'm trying to write some tests for a controller, but ALL the documentation/tutorials/etc on this demonstrate with functions and variables on $scope. What if you want to test something NOT on $scope?

Ex:

app.controller('fakeCtrl', function($scope) {

    var foo = 'bar';

    function fooBar() {
        console.log('foo bar');
    }

});

Is there any way to unit test foo or fooBar()?

Here's what DOESN'T work:

describe("fake controller", function(){

    beforeEach(module('app'));

    var $controller;

    beforeEach(inject(function(_$controller_, $rootScope){
        $controller = _$controller_;
        $scope = $rootScope.$new();
    }));

    describe('foo property', function() {
        it('is bar', function() {
          var controller = $controller('fakeCtrl', { $scope: $scope });
          expect(controller.foo).toEqual('bar');
        });
    });
   ...

Upvotes: 4

Views: 1870

Answers (2)

Artem Vovsia
Artem Vovsia

Reputation: 1570

There is no way in javascript to access local(declared inside function) function or variable from outside scope. You have some options to test this:

  1. Declare function/variable on scope.
  2. Move function/variable to angular service and test that service
  3. Test function/variable indirectly, by testing methods on scope that use that function/value

I prefer to move such functions/variables to angular services, but it depends on their purpose.

Upvotes: 1

Codringher
Codringher

Reputation: 141

You can not. Variable foo and function fooBar are inaccessible outside the scope of your controller constructor. You can however do something like that:

app.controller('fakeCtrl', function($scope) {
  this.foo = 'bar';
  this.fooBar() {
    console.log('foo bar');
  }
});

And than:

(...)
describe('foo property', function() {
    it('is bar', function() {
      var controller = $controller('fakeCtrl', { $scope: $scope });
      expect(controller.foo).toEqual('bar');
    });
});

In the test you have described foo as a property, but in your controller foo is just variable not property.

Edit: Check https://docs.angularjs.org/api/ng/directive/ngController and controller as syntax.

Upvotes: 3

Related Questions