ocombe / ocLazyLoad

Lazy load modules & components in AngularJS
https://oclazyload.readme.io
MIT License
2.63k stars 510 forks source link

ocLazyLoad with Karma and Webpack #437

Closed Waltari10 closed 4 years ago

Waltari10 commented 4 years ago

Hey,

We are using Karma for unit tests and Webpack for bundling. I get the following error when running tests:

HeadlessChrome 80.0.3987 (Windows 10.0.0) SiteDocsController updates site when documents id is changed FAILED Error: [$controller:ctrlreg] The controller with the name 'SiteDocsController' is not registered. https://errors.angularjs.org/1.7.9/$controller/ctrlreg?p0=SiteDocsController at eval (webpack:///./node_modules/angular/angular.js?:141:12) at $controller (webpack:///./node_modules/angular/angular.js?:11683:17) at node_modules/angular-mocks/angular-mocks.js:2555:14 at UserContext. (tests/unit/site-docs.controller.test.js:22:18) Expected spy updateSite to have been called. at UserContext. (tests/unit/site-docs.controller.test.js:69:40)

so basically it doesn't seem to be initializing the SiteDocsController code.

The SiteDocsController file looks like this:

'use strict';

export default angular
  .module('app.core')
  .controller('SiteDocsController', SiteDocsController);

SiteDocsController.$inject = ['$scope'];

function SiteDocsController($scope) {

    //... code here
}

And I import it dynamically like so:

  ...

  function lazyLoadSiteDocs ($transition$) {
    const $ocLazyLoad = $transition$.injector().get('$ocLazyLoad');
    import('./site-docs.controller.js')
      .then(res => $ocLazyLoad.load(res.default));
  }

  ...

      .state('main.sites.site.manage.docs', {
        url: '/docs',
        templateUrl: '/html/site-docs.html',
        controller: 'SiteDocsController as vm',
        lazyLoad: lazyLoadSiteDocs,
      })

This works great when running the app, but when testing it, not so much.

Here is our Karma config:

const path = require('path');

module.exports = function(config) {
  config.set({
    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: './',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine', 'sinon', 'source-map-support'],

    // list of files / patterns to load in the browser
    files: [
      'src/main/webapp/inc/**/*.test.js',
      'src/main/webapp/anonymousreport/index.js',
      'src/main/webapp/index.js',
      'node_modules/angular-mocks/angular-mocks.js',
      'node_modules/bardjs/bard.js',
      'tests/unit/mock.js',
      'node_modules/karma-read-json/karma-read-json.js',
      'tests/unit/*.js',
      'tests/unit/**/*.js',
      'tests/globals.js',
      { pattern: 'tests/mock/**/*.json', watched: true, served: true, included: false },
    ],

    webpack: {
      mode: 'development',
      module: {
        rules: [
          { test: /\.js/, loader: 'imports-loader?define=>false' },
          {
            test: /\.m?js$/,
            exclude: /(node_modules|bower_components)/,
            use: {
              loader: 'babel-loader',
              options: {
                presets: ['@babel/preset-env'],
              },
            },
          },
        ],
      },
    },

    preprocessors: {
      //add webpack as preprocessor to support require() in test-suits .js files
      'src/main/webapp/inc/**/*.test.js': ['webpack', 'coverage'],
      './tests/*.js': ['webpack', 'coverage'],
      'src/main/webapp/anonymousreport/index.js': ['webpack', 'coverage'],
      'src/main/webapp/index.js': ['webpack', 'coverage'],
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress', 'coverage'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher

    browsers: ['ChromeHeadlessNoSandbox'],
    customLaunchers: {
      ChromeHeadlessNoSandbox: {
        base: 'ChromeHeadless',
        flags: ['--no-sandbox'],
      },
    },

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: true,

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity,

  });
};

So how can I initialize dynamically loaded files in the projects unit tests? Thank you!

Waltari10 commented 4 years ago

I tried importing the lazily loaded files in a separate file and then adding that file to Karmas files in config. This worked except that the tests get stuck. Maybe a promise is not resolving?

Waltari10 commented 4 years ago

Okay, the tests getting stuck was an unrelated issues to this. Apparently we just hit the threshold of having too many tests and we ran out memory. Allocating more fixed the issue, and including the lazily loaded files in a separate file for the Karma tests seem to work fine for now.