简体   繁体   中英

[web-server]: 404: /@angular/core/testing, systemjs, karma, angular2, jspm

I'm using systemjs, karma, angular2 and jspm. The project is running fine. It's when I run the tests I get issues. It's saying that it can't find the core testing library. I'm not sure where to change this configuration.

any help is appreciated.

Jim.

-- unit test

import {it, describe, expect, beforeEach, inject} from '@angular/core/testing'
import {myCOmponent} from 'path to my comonent';

describe('myCOmponent ', () => {
  it('should have the component of defined', () => {
    expect(myCOmponent).toBeDefined();
  });
});

---- karma conf

module.exports = function(config) {
    config.set({

        basePath: '',

        frameworks: ['jasmine'],

        files: [
            // paths loaded by Karma
            {pattern: 'jspm_packages/system-polyfills.js', included: true, watched: true},
            {pattern: 'jspm_packages/system.src.js', included: true, watched: true},
            {pattern: 'node_modules/es6-shim/es6-shim.js', included: true, watched: true},
            {pattern: 'node_modules/angular2-polyfill/bundles/angular2-polyfill.js', included: true, watched: true},
            {pattern: 'jspm_packages/npm/@angular/core/testing', included: true, watched: true},
            {pattern: 'karma-test-shim.js', included: true, watched: true},


        // paths to support debugging with source maps in dev tools
        {pattern: 'app/**/*.ts', included: false, watched: false},
        ],

        // proxied base paths
        proxies: {
            // required for component assests fetched by Angular's compiler
            "/app/": "/base/app/"
        },

        preprocessors: {
            // source files, that you wanna generate coverage for
            // do not include tests or libraries
            // (these files will be instrumented by Istanbul)
            'app/**/*.js': ['coverage']
        },

        htmlReporter: {
            outputFile: 'reports/test/index.html'
        },

        // optionally, configure the reporter
        coverageReporter: {
            type: 'json',
            dir: 'reports/',
            subdir: '.',
            file: 'coverage.json'
        },

        reporters: ['progress', 'html', 'coverage'],
        port: 9876,
        colors: true,
        logLevel: config.LOG_INFO,
        autoWatch: true,
        browsers: ['Chrome'],
        singleRun: false
    })
}

--- karma shim

// Tun on full stack traces in errors to help debugging
// Error.stackTraceLimit = Infinity;
Error.stackTraceLimit = 0;


jasmine.DEFAULT_TIMEOUT_INTERVAL = 3000;

// // Cancel Karma's synchronous start,
// // we will call `__karma__.start()` later, once all the specs are loaded.
__karma__.loaded = function() {};


System.config({
    packages: {
        'base/app': {
            defaultExtension: false,
            format: 'register',
            map: Object.keys(window.__karma__.files).
            filter(onlyAppFiles).
            reduce(function createPathRecords(pathsMapping, appPath) {
                // creates local module name mapping to global path with karma's fingerprint in path, e.g.:
                // './hero.service': '/base/public/app/hero.service.js?f4523daf879cfb7310ef6242682ccf10b2041b3e'
                var moduleName = appPath.replace(/^\/base\/app\//, './').replace(/\.js$/, '');
                pathsMapping[moduleName] = appPath + '?' + window.__karma__.files[appPath]
                return pathsMapping;
            }, {})

        }
    }
});

System.import('@angular/core/testing').then(function(testing) {
        console.log(testing);
    return System.import('@angular/platform-browser-dynamic/testing').then(function(providers) {
        testing.setBaseTestProviders(providers.TEST_BROWSER_PLATFORM_PROVIDERS,
            providers.TEST_BROWSER_APPLICATION_PROVIDERS);
    });
}).then(function() {
    return Promise.all(
        Object.keys(window.__karma__.files) // All files served by Karma.
            .filter(onlySpecFiles)
            // .map(filePath2moduleName)        // Normalize paths to module names.
            .map(function(moduleName) {
                // loads all spec files via their global module names (e.g. 'base/public/app/hero.service.spec')
                return System.import(moduleName);
            }));
})
    .then(function() {
        __karma__.start();
    }, function(error) {
        __karma__.error(error.stack || error);
    });


function filePath2moduleName(filePath) {
    return filePath.
    replace(/^\//, '').              // remove / prefix
    replace(/\.\w+$/, '');           // remove suffix
}


function onlyAppFiles(filePath) {
    return /^\/base\/app\/.*\.js$/.test(filePath)
}


function onlySpecFiles(path) {
    return /^\/base\/test\/.*\.js$/.test(path);
}

So there's two parts to configuring this. You have the Karma config and you have the SystemJS config. Karma is the server, so you need to include all the files in the server just like you would any application. The files array in the karma.conf is where you list all the files that should be included in the server. So currently you're missing a bunch of Angular files. You can simply do the following to include all of them

{ pattern: 'jspm_packages/npm/@angular/**/*.js', included: false, watched: false },
{ pattern: 'jspm_packages/npm/@angular/**/*.js.map', included: false, watched: false },

This uses a pattern to include all the @angular files. include: false because you don't want them added as <script> s to the index page used in the karma server. watched: false because you don't want Karma to watch them in watch mode.

There are also other files that you will probably need, like rxjs . Take a look at the karma.conf from the Angular 2 quickstart for a list of all the files they include.

You will also notice the systemjs.config.js file. If you are using SystemJS as the module loader for the application, then you should have this file. This file loads all the modules needed for the application, so you will need them for the test also.

Then you need to configure SystemJS for testing. You have the application systemjs.config.js file, but this is only for the main application. You still need to load the @angular modules for testing, like @angular/core/testing . These are not included in the application systemjs.conf.js file because you don't need these testing files in the application. This is what the karma-test-shim is for.

So in you karma-test-shim , you need to configure SystemJS for loading the testing modules. You can look at the karma-test-shim from the Angular 2 quickstart to see how they configure it. You will need to create a mapping so that files can be loaded with a shortname as opposed to the full path. For example

System.config({
  paths: {
    'jspm:': 'jspm_packages/npm/'
  },
  baseURL: 'base',

  map: {
    '@angular/core/testing': 'jspm:@angular/core/bundles/core-testing.umd.js',
    '@angular/common/testing': 'jspm:@angular/common/bundles/common-testing.umd.js',
    '@angular/compiler/testing': 'jspm:@angular/compiler/bundles/compiler-testing.umd.js',
    '@angular/platform-browser/testing': 'jspm:@angular/platform-browser/bundles/platform-browser-testing.umd.js',
    '@angular/platform-browser-dynamic/testing': 'jspm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js',
    '@angular/http/testing': 'jspm:@angular/http/bundles/http-testing.umd.js',
    '@angular/router/testing': 'jspm:@angular/router/bundles/router-testing.umd.js',
    '@angular/forms/testing': 'jspm:@angular/forms/bundles/forms-testing.umd.js',
  },
});

If you look at the paths , you will see that it just sets a prefix so that you don't need to type as much later. This prefix will be used when you create the mappings.

Then in the map you will see that aliases are created. For example

'@angular/core/testing': 'jspm:@angular/core/bundles/core-testing.umd.js',

See here that the mapping @angular/core/testing is mapped to the actual module file, using the paths prefix mentioned earlier. This is how we are able to do

import { TestBed } from '@angular/core/testing'

System.import('@angular/core/testing')

It's because of the mapping that we are able to do this. If we don't have the mappings, SystemJS will look for a file name @angular/core/testing which it won't find, hence the 404.

I think this should give you enough information to help you figure out what you need to do. Review the files in the quickstart I linked to, as a reference if you get stuck.

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