How to you test an angularjs module defined inside

2019-05-09 16:52发布

问题:

how do I test this module on jasmine ? The problem is that it's very difficult to test the $controller because the function is hidden inside a closure, it’s very difficult to test them.

In other words, given the module definition below, writing a unit test for MainCtrl seems impossible.

(function () {

    'use strict';

    angular.module('app', []);

    function MainCtrl() {
      var mc = this;
      mc.obj = {
        val : 50  
      };
    }

    angular.module('app').controller('MainCtrl', MainCtrl);

} () );

and the "typical" jasmine test

describe('app', function(){

  beforeEach(module('app'));

  it('should create an objet with val 50', inject(function(_$controller_) {
    var scope = {},
        ctrl = _$controller_('MainCtrl', {$scope:scope});

    expect(scope.obj.val).toBe(50); // returns Expected undefined to be 50.
  }));

});

When angular inject the _$controller_ service inside the jasmine test function, The instance of the controller created returns with an undefined $scope.

So How can you test it?

My search on StackOverflow for a solution to this problem, didn't give me the answer I was looking for so I implemented one of my own.

回答1:

It can be tested with jasmine simply by doing this :

describe('app', function () {

    var $controller;

    beforeEach(function () {

        module('app');

        inject(function (_$controller_) {

            $controller = _$controller_('MainCtrl');

        });
    });

    //-- spec - test controller

    describe('Controller : MainCtrl', function () {

        it('should create an object with val 50', function () {

            expect($controller.obj.val).toBe(50);

        });
    });

});

here's a jsfiddle for it

Hope it helps !



回答2:

The problem is here

var scope = {}, ctrl = _$controller_('MainCtrl', {$scope:scope});

You're importing undefined scope. You need to do something like this:

  1. Inject $rootScope : inject(function (_$controller_, _$rootScope_)

  2. Construct new scope: var scope = $rootScope.$new();

  3. Build controller: var ctrl = _$controller_('MainCtrl', {$scope: scope});