My current web app is built using Typescript 2.4.2 and compiled with the latest Webpack version (2.7.0).
I am in the process of incorporating Karma tests utilizing Jasmine as the assertion library.
Below is my karma configuration file:
'use strict';
const webpack = require('./webpack.config');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const _ = require('lodash');
_.remove(webpack.plugins, plugin => plugin instanceof CleanWebpackPlugin);
webpack.module.rules.forEach(rule => {
if (rule.loader === 'ts-loader') {
rule.exclude = /sg\.d\.ts/;
}
});
module.exports = function (config) {
config.set({
webpack,
mime: {
'text/x-typescript': ['ts','tsx']
},
// base path used to resolve all patterns (e.g., files, exclude)
basePath: '',
// frameworks to utilize
frameworks: ['jasmine'],
// list of files/patterns to load in the browser
files: [
{ pattern: 'app/scripts/**/*.test.ts', watched: true}
],
preprocessors: {
"app/scripts/**/*.test.ts": ["webpack"]
},
exclude: [],
reporters: ['progress', 'mocha'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['jsdom', /*'Chrome'*/],
singleRun: false,
concurrency: Infinity
})
}
The initial test suite ran smoothly, resembling this structure:
import { default as moduleName } from "../module";
import { ListService, IListRequest } from "./listService";
import * as angular from 'angular';
import "angular-mocks";
import "jasmine";
const { module, inject } = angular.mock;
describe("List service", () => {
let serviceToTest: ListService;
let rootScope: ng.IRootScopeService;
let httpBackend: ng.IHttpBackendService;
beforeEach(module(moduleName));
beforeEach(() => {
inject(['$rootScope', '$httpBackend', ListService.SERVICE_NAME,
($rootScope: ng.IRootScopeService, $httpBackend: ng.IHttpBackendService, listService: ListService) => {
serviceToTest = listService;
rootScope = $rootScope;
httpBackend = $httpBackend;
}]);
});
it("service should not be null", () => {
expect(serviceToTest).toBeDefined();
});
// Additional tests
});
However, as soon as I tried adding another test suite for a separate service, issues arose:
import { default as moduleName } from "../module";
import { RedirectionService } from "./RedirectionService";
import * as angular from 'angular';
import "angular-mocks";
import "jasmine";
const { module, inject } = angular.mock;
describe('Redirection service', () => {
});
You might have noticed that the second test suite is presently empty.
The issue emerges when Angular begins throwing errors upon the addition of the second suite - attempting to load Angular and ng-mock twice, once for each new imported file.
An error message surfaces stating:
Error: [$injector:modulerr] Failed to instantiate module ngLocale due to: RangeError: Maximum call stack size exceeded
After conducting a swift Google search, numerous threads suggest that the problem arises when Karma loads ng-mock twice. Inspecting the code on Chrome confirms that the initialization of ngMock fails, triggering a warning from Angular about its double loading.
What measures can I take to address this situation? It appears that Karma treats each test file independently, neglecting to bundle Angular through Webpack into a singular module but rather compiling each file individually and re-adding Angular and ng-mock.