简体   繁体   中英

Angular 2 testing karma with webpack Can't find variable: Map

I am trying to test my directive with karma and webpack. This is the karma config file

module.exports = function (config) {
    config.set({
        basePath: './',
        frameworks: ["jasmine"],
        files: [
            {
            pattern: 'directive.spec.ts',
            watched: false
        }],
        exclude: [],
        preprocessors: {
            'directive.spec.ts': ['webpack', 'sourcemap']
        },
        webpackServer: {
            noInfo: true
        },
        port: 9876,
        colors: true,
        logLevel: config.LOG_INFO,
        autoWatch: false,
        browsers: [
            "PhantomJS"
        ],
        singleRun: true,
        reporters: ['mocha'],
        webpack: {
            resolve: {
                extensions: ['', '.ts', '.js'],
                modulesDirectories: ['node_modules', '.'],
            },
            module: {
                loaders: [{
                    test: /\.ts$/,
                    loader: 'awesome-typescript-loader'
                }]
            },
            stats: {
                colors: true,
                reasons: true
            },
            debug: true,
            devtool: 'inline-source-map'
        }
    });
};

And the directive.spec.ts:

import { MyDirective } from './directive';
import {TestComponent} from './test';
import {
  async,
  inject,
  TestBed,
} from '@angular/core/testing';

describe('TestComponent', () => {

  let fixture: any;

beforeEach(() => {
  fixture = TestBed.configureTestingModule({
    declarations: [ TestComponent, MyDirective]
  })
  .createComponent(TestComponent);
  fixture.detectChanges();
});

  it('should work', () => {
    expect(true).toBe(true);
  });

But when I am trying to run my test I am getting this error:

PhantomJS 2.1.1 (Mac OS X 0.0.0) ERROR ReferenceError: Can't find variable: Map at directive.spec.ts:1380

What am I missing here?

Please follow these steps. It worked for me:

1) Create a "karma-main.js" file with following code

 require('core-js/es6'); require('core-js/es7/reflect'); require('zone.js/dist/zone'); require('zone.js/dist/long-stack-trace-zone'); require('zone.js/dist/proxy'); require('zone.js/dist/sync-test'); require('zone.js/dist/jasmine-patch'); require('zone.js/dist/async-test'); require('zone.js/dist/fake-async-test'); var appContext = require.context('<Source code root folder>', true, /\\.spec\\.ts/); // Assuming test case files ends with spec.ts appContext.keys().forEach(appContext); var testing = require('@angular/core/testing'); var browser = require('@angular/platform-browser-dynamic/testing'); testing.TestBed.initTestEnvironment(browser.BrowserDynamicTestingModule, browser.platformBrowserDynamicTesting()); 

2) Your karma.conf.js file should look like

 var webpackConfig = require('./webpack.config') module.exports = function(config) { config.set({ // base path that will be used to resolve all patterns (eg. files, exclude) basePath: '', plugins: [ 'karma-jasmine', 'karma-PhantomJS-launcher', 'karma-webpack' ], webpack: webpackConfig, // frameworks to use // available frameworks: https://npmjs.org/browse/keyword/karma-adapter frameworks: ['jasmine'], // list of files / patterns to load in the browser files: [ { pattern: '<relative path to karma-main.js>', watched: false } ], // list of files to exclude exclude: [ ], // preprocess matching files before serving them to the browser // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor preprocessors: { '<relative path to karma-main.js>': ['webpack'] }, // test results reporter to use // possible values: 'dots', 'progress' // available reporters: https://npmjs.org/browse/keyword/karma-reporter reporters: ['progress'], // 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: ['PhantomJS'], // Continuous Integration mode // if true, Karma captures browsers, runs the tests and exits singleRun: false, // Concurrency level // how many browser should be started simultaneous concurrency: Infinity }) } 

Here is my guess: somewhere in the code you use a class Map which appeared in ES6. But PhantomJS doesn't know about this class yet since it's something too new.

So there are 3 choices:

  • Get rid of usage of Map and use only current JS features (like Object properties) - the cleanest approach.
  • Use transpiler for transforming your ES6 code into ES5 that's well understood by modern browser. This has huge disadvantages as it will mess with your line numbers and you may have to sacrifice the possibility to debug some of the code.
  • Use polyfills that implement ES6 features as functions in external libraries (as Sachin Gaur suggested )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM