我正在处理在不同环境下进行测试的一些问题:
我做了两个不同的karma-conf和karma-test-shim,一个用于SRC,另一个用于DIST。 在SRC中,因为我主要在fakeAsync上下文中对组件执行测试,所以我在karma的启动时缓存我的所有模板和.css,如下面的karma-test-shim所示,以避免XHR错误。
果报测试shim.src.js
// Turn on full stack traces in errors to help debugging
Error.stackTraceLimit = Infinity;
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
var karmaFiles = Object.keys(window.__karma__.files); // All files served by Karma.
window.$templateCache = {}; // deckaring Window template cache for caching .html template and .css
// Cancel Karma's synchronous start,
// we will call `__karma__.start()` later, once all the specs are loaded.
__karma__.loaded = function () { };
// Just a special configuration for Karma and coverage
System.config({
packages: {
"@angular/core/testing": { main: "../../../../../../node_modules/@angular/core/bundles/core-testing.umd.js" },
"@angular/compiler/testing": { main: "../../../../base/node_modules/@angular/compiler/bundles/compiler-testing.umd.js" },
"@angular/common/testing": { main: "../../../../base/node_modules/@angular/common/bundles/common-testing.umd.js" },
"@angular/http/testing": { main: "../../../../base/node_modules/@angular/http/bundles/http-testing.umd.js" },
"@angular/router/testing": { main: "../../../../../../node_modules/@angular/router/bundles/router-testing.umd.js" },
"@angular/platform-browser/testing": { main: "../../../../base/node_modules/@angular/platform-browser/bundles/platform-browser-testing.umd.js" },
"@angular/platform-browser-dynamic/testing": { main: "../../../../base/node_modules/@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js" }
},
meta: {
"src/*": { format: "register" }, // Where covered files located
"packages/*": { format: "register" } // Where covered files located
}
});
Promise.all([
System.import('@angular/core/testing'),
System.import('@angular/platform-browser-dynamic/testing'),
System.import('@angular/platform-browser-dynamic') // Contains RESOURCE_CACHE_PROVIDER
]).then(function (providers) {
var testing = providers[0];
var testingBrowserDynamic = providers[1];
var browserDynamic = providers[2];
testing.TestBed.initTestEnvironment(
testingBrowserDynamic.BrowserDynamicTestingModule,
testingBrowserDynamic.platformBrowserDynamicTesting()
);
testing.TestBed.configureCompiler({
providers: [
browserDynamic.RESOURCE_CACHE_PROVIDER
]
})
// Import main module
}).then(function () {
return Promise.all(
karmaFiles
.filter(onlySpecFiles)
.map(file2moduleName)
.map(function (path) {
return System.import(path).then(function (module) {
if (module.hasOwnProperty('main')) {
module.main();
} else {
throw new Error('Module ' + path + ' does not implement main() method.');
}
});
}));
})
// Caching all component's templates files (.html/.css)
.then(function () {
return Promise.all(
karmaFiles
.filter(function (filename) {
var template = filename.endsWith('.html');
var css = filename.endsWith('.css');
return template || css;
})
.map(function (filename) {
return new Promise(function(resolve, reject) {
$.ajax({
type: 'GET',
url: filename,
dataType: 'text',
success: function (contents) {
filename = filename.replace("/base", "..");
window.$templateCache[filename] = contents;
resolve();
}
})
})
})
)
})
.then(function () {
__karma__.start();
}, function (error) {
console.error(error.stack || error);
__karma__.start();
});
// Filter spec files
function onlySpecFiles(path) {
return /\.spec\.js$/.test(path);
}
// Normalize paths to module names.
function file2moduleName(filePath) {
return filePath.replace(/\\/g, '/')
.replace(/^\/base\//, '');
}
到目前为止一直很好,但我开始在以下规范中遇到问题:
loginPage.spec.js
[...]
import { LoginPageComponent } from "loginPage";
import { RESOURCE_CACHE_PROVIDER } from "@angular/platform-browser-dynamic";
@Component({
selector: "loginpage-host",
template: "<loginPage></loginPage>"
})
export class LoginPageHostComponent {
@ViewChild(LoginPageComponent)
public loginPageComponent;
}
export function main() {
describe('LoginPageComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule.withRoutes([]),CommonModule, HttpModule, CoreModule, ComponentsModule, GlobalizationModule],
declarations: [LoginPageHostComponent, LoginPageComponent],
providers: [
MockBackend,
BaseRequestOptions,
{
provide: AuthHttp,
useFactory: (backend: ConnectionBackend, options: BaseRequestOptions) => new Http(backend, options),
deps: [MockBackend, BaseRequestOptions]
},
{
provide: Http,
useFactory: (backend: ConnectionBackend, options: BaseRequestOptions) => new Http(backend, options),
deps: [MockBackend, BaseRequestOptions]
},
{
provide: Configuration,
useFactory: () => new Configuration()
}
]
})
// TestBed.configureCompiler({
// providers: [RESOURCE_CACHE_PROVIDER]
// });
});
it('should work',
fakeAsync(() => {
TestBed
.compileComponents()
.then(() => {
let fixture = TestBed.createComponent(LoginPageHostComponent);
let logPageHostComponentInstance = fixture.debugElement.componentInstance;
expect(logPageHostComponentInstance).toEqual(jasmine.any(LoginPageHostComponent));
expect(logPageHostComponentInstance.loginPageComponent).toEqual(jasmine.any(LoginPageComponent));
fixture.destroy();
discardPeriodicTasks();
});
}));
});
}
在SRC上我收到此错误:
Chrome 56.0.2924(Windows 10 0.0.0)LoginPageComponent应该可以使用 FAILED错误:无法在假异步测试中制作XHR。
如果我手动将RESOURCE_CACHED_PROVIDER提供给它可以运行的规范:
TestBed.configureCompiler({
providers: [RESOURCE_CACHE_PROVIDER]
});
但它在DIST上失败,因为没有为loginPage加载缓存模板。
答案 0 :(得分:0)
请参阅:Angular2 tests and RESOURCE_CACHE_PROVIDER global
我们找到了一个解决方案,但不是基于Angular提供商。
我们开发了一个简单的业力预处理器,仅用于测试:
preprocessors: {
"**/*.component.js": ["generic"]
},
然后预处理器只使用gulp-inline-ng2-template
解析器
genericPreprocessor: {
rules: [{
process: function (content, file, done, log) {
// Prepare content for parser
file.contents = new Buffer(content);
// Every file has a parser
var parse = require('gulp-inline-ng2-template/parser')(file, { base: "packages/", useRelativePaths: false });
// Call real parse function
parse(function (err, contents) {
// Callback with content with template and style inline
done(contents);
});
}
}]
},