尝试使用Karma运行Angular2 + TypeScript测试时遇到一些问题。
这是我的情景:
让我们假设我有一个简单的管道:
import {PipeTransform, Pipe, Injectable} from 'angular2/core';
@Injectable()
@Pipe({name: 'ucfirst'})
export class UcFirstPipe implements PipeTransform {
transform(text:string):string {
return text.slice(0, 1).toUpperCase() + text.slice(1);
}
}
以及以下规范:
import {it, describe, expect, beforeEach, inject} from 'angular2/testing';
import {UcFirstPipe} from "./ucfirst";
describe('UcFirstPipe Tests', () => {
let pipe:UcFirstPipe;
beforeEach(() => {
pipe = new UcFirstPipe();
});
it('Should capitalize first word in a string', () => {
var result = pipe.transform('foo bar baz');
expect(result).toEqual('Foo bar baz');
});
});
这是我的目录结构:
src/
pipes/
- ucfirst.ts
- ucfirst.spec.ts
使用Karma编译和运行测试时,使用此目录结构一切正常。 但是当我将ucfirst * .ts移动到管道下的子目录时,例如:
src/
pipes/
string/
- ucfirst.ts
- ucfirst.spec.ts
我收到以下错误:
Error: XHR error (404 Not Found) loading .../compiled/pipes/string/ucfirst
Error loading .../compiled/pipes/string/ucfirst as "./ucfirst" from ../compiled/pipes/string/ucfirst.spec.js
这些是我的配置文件:
tsconfig.json
{
"files": [
"./typings/**/*.d.ts"
],
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"sourceMap": true,
"removeComments": true,
"declaration": true,
"noImplicitAny": false,
"preserveConstEnums": true
},
"exclude": [
"node_modules"
]
}
karma.conf.js:
module.exports = function(config) {
config.set({
basePath: '.',
frameworks: ['jasmine'],
files: [
// paths loaded by Karma
{pattern: 'node_modules/angular2/bundles/angular2-polyfills.js', included: true, watched: true},
{pattern: 'node_modules/systemjs/dist/system.src.js', included: true, watched: true},
{pattern: 'node_modules/rxjs/bundles/Rx.js', included: true, watched: true},
{pattern: 'node_modules/angular2/bundles/angular2.dev.js', included: true, watched: true},
{pattern: 'node_modules/angular2/bundles/testing.dev.js', included: true, watched: true},
{pattern: 'karma-test-shim.js', included: true, watched: true},
// paths loaded via module imports
{pattern: 'compiled/**/*.js', included: false, watched: true},
// paths to support debugging with source maps in dev tools
{pattern: 'src/**/*.ts', included: false, watched: false},
{pattern: 'compiled/**/*.js.map', included: false, watched: false}
],
// proxied base paths
proxies: {
// required for component assests fetched by Angular's compiler
'/src/': '/base/src/'
},
port: 9876,
logLevel: config.LOG_INFO,
colors: true,
autoWatch: true,
browsers: ['Chrome'],
// Karma plugins loaded
plugins: [
'karma-jasmine',
'karma-coverage',
'karma-chrome-launcher'
],
// Coverage reporter generates the coverage
reporters: ['progress', 'dots', 'coverage'],
// Source files that you wanna generate coverage for.
// Do not include tests or libraries (these files will be instrumented by Istanbul)
preprocessors: {
'compiled/**/!(*spec).js': ['coverage']
},
coverageReporter: {
reporters:[
{type: 'json', subdir: '.', file: 'coverage-final.json'}
]
},
singleRun: true
})
};
业力试验垫片:
// Tun on full stack traces in errors to help debugging
Error.stackTraceLimit = Infinity;
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;
// // Cancel Karma's synchronous start,
// // we will call `__karma__.start()` later, once all the specs are loaded.
__karma__.loaded = function() {};
System.config({
packages: {
'base/compiled': {
defaultExtension: false,
format: 'cjs',
map: Object.keys(window.__karma__.files).filter(onlyAppFiles).reduce(createPathRecords, {})
}
}
});
System.import('angular2/src/platform/browser/browser_adapter')
.then(function(browser_adapter) { browser_adapter.BrowserDomAdapter.makeCurrent(); })
.then(function() { return Promise.all(resolveTestFiles()); })
.then(function() { __karma__.start(); }, function(error) { __karma__.error(error.stack || error); });
function createPathRecords(pathsMapping, appPath) {
// creates local module name mapping to global path with karma's fingerprint in path, e.g.:
// './vg-player/vg-player':
// '/base/compiled/vg-player/vg-player.js?f4523daf879cfb7310ef6242682ccf10b2041b3e'
var pathParts = appPath.split('/');
var moduleName = './' + pathParts.slice(Math.max(pathParts.length - 2, 1)).join('/');
moduleName = moduleName.replace(/\.js$/, '');
pathsMapping[moduleName] = appPath + '?' + window.__karma__.files[appPath];
return pathsMapping;
}
function onlyAppFiles(filePath) {
return /\/base\/compiled\/(?!.*\.spec\.js$).*\.js$/.test(filePath);
}
function onlySpecFiles(path) {
return /\.spec\.js$/.test(path);
}
function resolveTestFiles() {
return Object.keys(window.__karma__.files) // All files served by Karma.
.filter(onlySpecFiles)
.map(function(moduleName) {
// loads all spec files via their global module names (e.g.
// 'base/compiled/vg-player/vg-player.spec')
return System.import(moduleName);
});
}