我认为我的配置合理:
karma.conf.js
module.exports = function (config) {
var dist = "dist/";
var src = "src/";
config.set({
basePath: '',
frameworks: ['jasmine'],
files: [
// System.js for module loading
'node_modules/systemjs/dist/system-polyfills.js',
'node_modules/systemjs/dist/system.src.js',
// Polyfills for older browsers
'node_modules/core-js/client/shim.min.js',
// Reflect and Zone.js
'node_modules/reflect-metadata/Reflect.js',
'node_modules/zone.js/dist/zone.js',
'node_modules/zone.js/dist/jasmine-patch.js',
'node_modules/zone.js/dist/async-test.js',
'node_modules/zone.js/dist/fake-async-test.js',
// RxJs.
{ pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },
{ pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false },
// Angular 2 itself and the testing library
{ pattern: 'node_modules/@angular/**/*.js', included: false, watched: false },
{ pattern: 'node_modules/@angular/**/*.js.map', included: false, watched: false },
'karma-test-shim.js',
// Widget's bundles
{ pattern: dist + 'widget-ui.min.css', included: true, watched: true },
{ pattern: 'node_modules/widget-angular/**/*.js', included: false, watched: true },
// Application bundles
{ pattern: dist + 'src/lib.bundle.js', included: true, watched: true },
{ pattern: dist + 'src/core.bundle.js', included: true, watched: true },
{ pattern: dist + 'src/about.bundle.js', included: true, watched: true },
{ pattern: dist + 'src/admin.bundle.js', included: true, watched: true },
{ pattern: 'src/test.bundle.js', included: true, watched: true },
// Paths to support debugging with source maps in dev tools
{ pattern: src + '**/*.ts', included: false, watched: true }
],
// proxied base paths
proxies: {
// Required for component assets fetched by Angular's compiler
'/dist/src/': '/base/dist/src/'
},
exclude: [src + 'jspm_packages/**/*.ts'],
reporters: ['progress'],
plugins: [
'karma-jasmine',
'karma-chrome-launcher'
],
port: 9876,
colors: true,
logLevel: config.LOG_DEBUG, // was LOG_INFO
autoWatch: true,
browsers: ['Chrome'],
singleRun: false
})
};
果报测试shim.js
Error.stackTraceLimit = Infinity;
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;
__karma__.loaded = function () {
};
function isTestSpecFile(path) {
return path.slice(-7) == 'spec.ts';
}
function extractModuleName(path) {
return path.replace("/base/src/", "");
}
var allTestSpecFiles = Object.keys(window.__karma__.files).filter(isTestSpecFile);
// Load our SystemJS configuration.
var packages = {
'rxjs': { defaultExtension: 'js' }
};
// Add angular packages to SystemJS config
[
'@angular/common',
'@angular/compiler',
'@angular/core',
'@angular/http',
'@angular/platform-browser',
'@angular/platform-browser-dynamic',
'@angular/router',
'@angular/upgrade'
].forEach(function (name) { packages[name] = { main: 'index.js', defaultExtension: 'js' }; });
System.config({
baseURL: '/base',
map: {
'rxjs': 'node_modules/rxjs',
'@angular': 'node_modules/@angular'
},
packages: packages
});
Promise.all([
System.import('@angular/core/testing'),
System.import('@angular/platform-browser-dynamic/testing/browser')
])
.then(function(modules) {
var testing = modules[0];
var testingBrowser = modules[1];
testing.setBaseTestProviders(
testingBrowser.TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
testingBrowser.TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS);
})
.then(function () {
// Finally, load all spec modules.
// This will run the tests directly.
return Promise.all(
allTestSpecFiles.map(extractModuleName).map(function (moduleName) {
return System.import(moduleName);
}));
})
.then(function() { __karma__.start(); }, function(error) { __karma__.error(error.stack || error); });
最后测试本身:
import {provide} from '@angular/core';
import {
beforeEach,
beforeEachProviders,
describe,
expect,
it,
inject,
async
} from '@angular/core/testing';
import {TestComponentBuilder, ComponentFixture} from '@angular/compiler/testing';
import {Injectable} from "@angular/core";
import 'rxjs/Rx'; // load the full rxjs
import { SimpleUserListComponent } from '../../admin/components/simple-user-list.component';
import { SimpleUserService } from "../../core/services/simple-user.service";
import { User } from "../../core/models/user";
@Injectable()
class MockUserService {
public getUsers() {
return Promise.resolve(<User[]>[{ "id": "999", "username": "ABC" }, { "id": "998", "username": "DEF" }]);
}
}
/// Delete this
describe('Smoke test', () => {
it('should run a passing test', () => {
expect(true).toEqual(true, 'should pass');
});
});
describe('SimpleUserListComponent with new', function () {
it('should instantiate component', () => {
expect(new SimpleUserListComponent()).toBeDefined('Whoopie!');
});
});
describe('SimpleUserListComponent', () => {
beforeEach(async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
.overrideProviders(SimpleUserListComponent, [{provide: SimpleUserService, useClass: MockUserService}])
.createAsync(SimpleUserListComponent)
.then((componentFixture: ComponentFixture) => {
this.listComponentFixture = componentFixture;
const element = this.listComponentFixture.nativeElement;
this.listComponentFixture.detectChanges();
});
})));
it('should render list', (done) => {
const element = this.listComponentFixture.nativeElement;
this.listComponentFixture.detectChanges();
var intervalID = setInterval(function(){
if (element.querySelectorAll('li').length == 2) {
expect(element.querySelectorAll('li').length).toBe(2);
clearInterval(intervalID);
}
done(); // call this to finish off the it block
}, 100);
});
});
我的非异步测试工作正常。
但是一旦我尝试异步测试设置,它就失败了:
Failed: No provider for TestComponentBuilder!
Error: DI Exception
at NoProviderError.BaseException [as constructor] (src/test.bundle.js:21783:21)
at NoProviderError.AbstractProviderError [as constructor] (src/test.bundle.js:19605:14)
at new NoProviderError (src/test.bundle.js:19629:14)
at ReflectiveInjector_._throwOrNull (src/test.bundle.js:19026:17)
at ReflectiveInjector_._getByKeyDefault (src/test.bundle.js:19050:23)
at ReflectiveInjector_._getByKey (src/test.bundle.js:19019:23)
at ReflectiveInjector_.get (src/test.bundle.js:18832:21)
at src/test.bundle.js:14453:32
...
我错过了什么?