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.