Patrick Duncan
Patrick Duncan

Reputation: 559

Dealing With Dependencies in angularjs Testing

This is for work (I have permission) so I can't post exact code.

So I have to test controllers of a large module. The module has a large config function with a bunch of controllers for the logic of the different pages.

For the actual application it's loaded with bower, which is irritating since I'm testing with Karma-Browserify and npm. So the the dependencies are a mess. I basically have to import everything that was loaded from bower.json to package.json.

This is my karma.conf.js:

module.exports = function(config) {
  config.set({
    basePath: 'resources',
    browserify: {
      debug: true,
      transform: [ 'browserify-shim' ]
    },
    browsers: [ 'PhantomJS' ],
    captureTimeout: 60000,
    client: {
      mocha: {}
    },
    files: [
      'tests/assist/test.js',
      'assets/scripts/libs/logger.min.js'
    ],
    frameworks: [ 'browserify', 'phantomjs-shim', 'mocha', 'chai' ],
    port: 8080,
    preprocessors: {
      'tests/assist/controller.js': [ 'browserify' ]
    },
    reporters: [ 'mocha', 'coverage' ],
    singleRun: true
  });
};

So the code below this is my test.js (removing some company-specific names). Also I need to put angular.mock. or it won't work

require('angular');
require('angular-mocks');

//Main module needs these
jQuery = require('jquery');
require('angular-bootstrap');
require('angular-recaptcha');
require('angular-ui-router');
require('ngstorage');
require(**The path to the main module**);
require(**The path to a service it uses**);
require(**The path to a service it uses**);
require(**The path to a service it uses**);

describe('Blah', function () {
  beforeEach(angular.mock.module('myApp'));

  var $controller;

  beforeEach(angular.mock.inject(function(_$controller_) {
    $controller = _$controller_;
  }));

  describe('blahblah', function () {
    it('sets loading to true', function () {
      var $scope = {};
      var controller = $controller('controller', {$scope: $scope});
      assert($scope.showLoading === true);
    });
  });
});

The main module:

(function() {
    'use strict';
})();


// Jquery noconflict
jQuery.noConflict();

var myApp = angular.module('myApp', ['ui.router', 'ngStorage', 'vcRecaptcha', 'ui.bootstrap']);

myApp.config(['$stateProvider', '$urlRouterProvider', '$locationProvider', function($stateProvider, $urlRouterProvider, $locationProvider) {
    ...
}])
.run([blah bunch of dependencies]) {
   ...
}]);

The controller (separate fie):

'use strict';

myApp.controller('controller', ['$scope', '$http', '$localStorage', 'service1', 'service2', 'service3',
    function ($scope, $http, $localStorage, service1, service2, service3) {
   ..
    }
...

As you can see I'm in dependency hell. I got the example test on the angular site to work, the main problem is with the dependencies and myApp not being visible to the controller. "ReferenceError: Can't find variable: myApp" in controllers/services

If anyone has a better way of going about testing I'm all ears.

Upvotes: 0

Views: 295

Answers (1)

Estus Flask
Estus Flask

Reputation: 222493

This is not about dependency hell, not about testing also.

The code seems to rely on myApp global variable, this is strictly opposite to what Angular modules are for.

myApp should be a local variable that is defined dynamically in each function scope

(function () {

var myApp = angular.module('myApp', [...]);
...

})();

(function () {

var myApp = angular.module('myApp');
myApp.controller('controller', ...)
...

})();

Upvotes: 2

Related Questions