[web-server]: 404错误:/@angular/core/testing,SystemJS,Karma,Angular2,jspm

3
我正在使用systemjs、karma、angular2和jspm进行开发,项目运行良好。但是当我运行测试时,出现了问题。错误提示显示找不到核心测试库,我不确定在哪里更改此配置。

感谢您的帮助。

Jim。

-- 单元测试

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配置文件

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);
}
1个回答

1

配置这个有两个部分。你需要配置Karma和SystemJS。Karma是服务器,所以你需要像任何应用程序一样在服务器上包含所有文件。在karma.conf中的files数组中列出应该包含在服务器中的所有文件。所以目前你缺少了很多Angular文件。你可以简单地执行以下操作来包含所有文件。

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

这里使用了一种模式来包含所有的 @angular 文件。include: false 的原因是你不想将它们添加为 <script> 标签到在 karma 服务器中使用的 index 页面中。watched: false 是因为你不想让 Karma 在 watch 模式下监视它们。
还有其他一些文件可能也需要,比如 rxjs。查看 Angular 2 快速入门的 karma.conf 可以找到他们所包含的所有文件列表。
你还会注意到 systemjs.config.js 文件。如果你正在使用 SystemJS 作为应用程序的模块加载器,则应该拥有此文件。此文件加载了应用程序所需的所有模块,因此您也需要它们进行测试。
然后您需要为测试配置SystemJS。您有应用程序systemjs.config.js文件,但这仅适用于主应用程序。您仍然需要加载用于测试的@angular模块,例如@angular/core/testing。这些未包含在应用程序systemjs.conf.js文件中,因为您不需要这些测试文件。这就是karma-test-shim的作用。
因此,在您的karma-test-shim中,您需要配置SystemJS以加载测试模块。您可以查看Angular 2快速入门中的karma-test-shim,以了解如何配置它。您将需要创建一个映射,以便可以使用短名称而不是完整路径加载文件。例如
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',
  },
});

如果你查看paths,你会发现它只是设置了一个前缀,以便以后不需要再输入那么多。这个前缀将在创建映射时使用。
然后在map中,你会看到别名被创建。例如:
'@angular/core/testing': 'jspm:@angular/core/bundles/core-testing.umd.js',

请看这里,@angular/core/testing 的映射与实际模块文件相对应,使用之前提到的 paths 前缀。这就是我们能够做到的方式。
import { TestBed } from '@angular/core/testing'

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

因为有了映射,我们才能做到这一点。如果没有映射,SystemJS将会寻找文件名为@angular/core/testing的文件,但它找不到,因此会出现404错误。
我认为这应该足够让您了解需要做什么了。如果您遇到困难,请参考我提供的quickstart中的文件。

感谢您提供如此全面的答案。我会尝试一下并告诉您结果如何。再次感谢。 - Jimi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接