Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular/Karma/Jasmine: TypeError: 'undefined' is not an object (evaluating 'scope.awesomeThings')

Trying to setup unit-tests for https://github.com/beeman/loopback-angular-admin.

app/modules/about/controllers/about.controller.js (I added $scope.awesomeThings to load the scope with something to test):

'use strict';
angular.module('com.module.about')
  /**
   * @ngdoc function
   * @name com.module.about.controller:AboutCtrl
   * @description
   * # AboutCtrl
   * Controller of the clientApp
   */
  .controller('AboutCtrl', function($scope) {
    $scope.angular = angular;
    $scope.awesomeThings = [1, 2];
  });

The jasmine test at client/test/modules/about/controllers/about.ctrl.js

'use strict';

describe('Controller: AboutCtrl', function () {
  var AboutCtrl,
    scope;

  // load the controller's module
  beforeEach(module('gettext'));
  beforeEach(module('ui.router'));
  beforeEach(module('com.module.about'));

  // Initialize the controller and a mock scope
  beforeEach(inject(function ($controller, $rootScope) {
    scope = $rootScope.$new();
    AboutCtrl = $controller('AboutCtrl', {
      '$scope': scope
    });
  }));

  it('should attach a list of awesomeThings to the scope', function () {
    expect(scope.awesomeThings.length).toBe(3);
  });
});

When I run this simple test, I get:

TypeError: 'undefined' is not a function (evaluating '$rootScope.addDashboardBox(gettextCatalog.getString('About'), 'bg-maroon',
      'ion-information', 0, 'app.about.index')')
    at client/app/modules/about/controllers/about.config.js:6
    at invoke (client/app/bower_components/angular/angular.js:4203)
    at client/app/bower_components/angular/angular.js:4025
    at forEach (client/app/bower_components/angular/angular.js:323)
    at createInjector (client/app/bower_components/angular/angular.js:4025)
    at workFn (client/app/bower_components/angular-mocks/angular-mocks.js:2425)
TypeError: 'undefined' is not an object (evaluating 'scope.awesomeThings')
    at client/test/modules/about/controllers/about.ctrl.js:21

If I set logLevel: LOG_DEBUG, the about* files show:

-> % grep about /tmp/karma-debug.log

    client/app/modules/about/app.about.js
    client/app/modules/about/controllers/about.config.js
    client/app/modules/about/controllers/about.controller.js
    client/app/modules/about/controllers/about.routes.js
    client/test/modules/about/controllers/about.ctrl.js
DEBUG [web-server]: serving (cached): client/app/modules/about/app.about.js
DEBUG [web-server]: serving (cached): client/app/modules/about/controllers/about.config.js
DEBUG [web-server]: serving (cached): client/app/modules/about/controllers/about.controller.js
DEBUG [web-server]: serving (cached): client/app/modules/about/controllers/about.routes.js
DEBUG [web-server]: serving (cached): client/test/modules/about/controllers/about.ctrl.js

I know I'm missing something basic, but I can't seem to find what.

like image 308
Mike Crowe Avatar asked Apr 30 '15 00:04

Mike Crowe


2 Answers

I didn't look carefully enough at the initial error. The actual error was in $rootScope.addDashboardBox, which indicated additional modules needed to be included.

Solution is for the test script to be:

  'use strict';

  describe('Controller: AboutCtrl', function () {
    var AboutCtrl,
      scope;

    // load the controller's module
    beforeEach(module('ui.router'));
    beforeEach(module('gettext'));
    beforeEach(module('formly'));
    beforeEach(module('angular-loading-bar'));
    beforeEach(module('lbServices'));
    beforeEach(module('com.module.core'));
    beforeEach(module('com.module.settings'));
    beforeEach(module('com.module.about'));

    // Initialize the controller and a mock scope
    beforeEach(inject(function ($controller, $rootScope) {
      scope = $rootScope.$new();
      AboutCtrl = $controller('AboutCtrl', {
        '$scope': scope
      });
    }));

    it('should attach a list of awesomeThings to the scope', function () {
      expect(scope.awesomeThings.length).toBe(3);
    });

  });
like image 193
Mike Crowe Avatar answered Nov 18 '22 06:11

Mike Crowe


For future me since it's the first result at Google.

Do look for external dependencies!

Karma's log is a bit misleading, the actual problem is the main module is not running. For example, angular-stripe, which is injected to karma.conf.js by Bower, requires actual Stripe JS library loaded otherwise crashes the whole application (which is very annoying itself). I have added this line to karma.conf.js:

files: [
  'https://js.stripe.com/v2',

and now it works.

like image 33
leitasat Avatar answered Nov 18 '22 06:11

leitasat