3

I am using this strategy to lazy-load stuff with RequireJS in my AngularJS app:

define([
  'src/services/dependency_resolver', // resolves promise when dependencies are `require`d
  'json!modules.json'
], function (dependencyResolver, modules) {
  var app = angular.module('myApp', [ 'ngRoute' ]);

  app.config(function ($controllerProvider, $routeProvider) {
    app.lazy = {
      controller: $controllerProvider.register
      // <...> other providers
    };

    angular.forEach(modules, function (moduleConfig) {
      angular.forEach(moduleConfig.routes, function (route) {
        $routeProvider.when(route.path, {
          templateUrl: route.templateUrl,
          controller: route.controller,
          resolve: dependencyResolver(moduleConfig.dependencies)
        });
      });
    });
  });

  return app;
});

But I'm not sure what is the correct way test a lazy-loaded controller. It is registered like this:

define(['src/app'], function (app) {
  app.lazy.controller('MainCtrl', function () {
    //
  });
});

And this is my current spec:

describe('`MainCtrl` controller', function () {

  var Ctrl,
      $scope;

  beforeEach(angular.mock.module('myApp'));

  beforeEach(function (done) {
    require(['module/main'], done);
  });

  beforeEach(function () {
    angular.mock.inject(function ($rootScope, $controller) {
      $scope = $rootScope.$new();

      Ctrl = $controller('MainCtrl', {
        $scope: $scope
      });
    });
  });

  it('should ...', function () {
    console.log(Ctrl);
  });

});

With this spec, an error occurs when controller is being registered, because app.lazy is undefined.

So the question is how to test such controllers?

Cheers!

2 Answers 2

1

I was experiencing a similar problem when writing my unit test using the "lazy" property to register my controller. The problem with this approach is that when in the context of a unit test, the module config block will not be executed and as a result, app.lazy will resolve to undefined.

To solve your problem, instead of using provider registration methods to set your properties of app.lazy, the provider registration method should be used to override their counterparts on the module. In other words, your config block should now become:

`app.config(function ($controllerProvider, $routeProvider) {  
    app.controller = $controllerProvider.register
    // <...> other providers  
    .......
}`

Instead of register your controller using (app.lazy):

`define(['src/app'], function (app) {
   app.lazy.controller('MainCtrl', function () {
   //
   });
});`

you can just define like this:

`define(['src/app'], function (app) {
   app.controller('MainCtrl', function () {
   //
   });
});`

And this should work! Hopefully this can help, and please let me know if this works out or not.

Sign up to request clarification or add additional context in comments.

Comments

0

First of all, thank you for the reference you provided - the article is really interesting.

Author of the article is using AngularJs providers to implement his strategy. The thing is, that AngularJs doesn't have providers for 'specs'. So my opinion is that you should omit this strategy in your unit tests.

On this basis, I think, that you should add AMD to your spec file. Define your controller as a dependency in your spec. After this, you may just require all your specs somewhere in main-spec.js and launch your testing framework.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.