混合 Angular 使用 Karma 进行的应用程序测试无法加载 HTML
Hybrid Angular App Testing with Karma Cannot Load HTML
我们有一个使用 karma 进行单元测试的混合 Angular 应用程序。我正在尝试添加我们的第一套测试,但我收到一些错误,表明 karma 无法找到 dashboard.component.html
。
查看:
import { Component, OnInit } from '@angular/core';
@Component({
templateUrl: './views/components/dashboard/dashboard.component.html'
})
export class DashboardComponent implements OnInit {
constructor() {}
ngOnInit() {
console.log('works!');
}
}
这是我的 karma.config.js
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['angular', 'jasmine'],
files: [
{ pattern: 'src/test.ts', watched: false },
{ pattern: 'dist/views/components/dashboard/dashboard.component.html', included: false, watched: true }
],
exclude: [],
preprocessors: {
'src/test.ts': ['webpack', 'sourcemap']
},
webpack: require('./webpack-base.config'),
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
singleRun: true,
concurrency: Infinity,
browsers: ['Chrome_Headless'],
customLaunchers: {
Chrome_Headless: {
base: 'Chrome',
flags: [
'--headless',
'--disable-gpu',
'--remote-debugging-port=9222'
]
},
Chrome_without_security: {
base: 'Chrome',
flags: [
'--headless',
'--disable-gpu',
'--remote-debugging-port=9222',
'--disable-web-security'
]
}
},
// workaround for typescript and chrome/headless
mime: {
'text/x-typescript': ['ts', 'tsx']
}
});
};
我们的混合应用程序是使用 Webpack 编译的。所有视图文件都复制到 /view
。这是我们的 webpack 文件:
/* eslint-env node */
const webpack = require('webpack');
const helpers = require('./helpers');
const path = require('path');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const extractSass = new ExtractTextPlugin({
filename: 'css/[name].[hash].css',
disable: process.env.NODE_ENV === 'development'
});
module.exports = {
mode: 'development',
entry: {
app: './src/js/index.ts'
},
resolve: {
extensions: ['.ts', '.js', '.html'],
alias: {
'@angular/upgrade/static':
'@angular/upgrade/bundles/upgrade-static.umd.js'
}
},
plugins: [
new CleanWebpackPlugin(['dist']),
// Workaround for angular/angular#11580
new webpack.ContextReplacementPlugin(
// The (\|\/) piece accounts for path separators in *nix and Windows
/angular(\|\/)core(\|\/)@angular/,
helpers.root('./src'), // location of your src
{} // a map of your routes
),
new HtmlWebpackPlugin({
template: './src/index.html',
inject: 'body'
}),
new CopyWebpackPlugin([
{ from: './src/views', to: 'views' },
{ from: './src/js/components', to: 'views/components', ignore: ['*.ts', '*.scss']},
{ from: './src/img', to: 'img' },
{ from: './src/config.js', to: '' }
]),
extractSass
],
devtool: 'inline-source-map',
devServer: {
contentBase: './dist',
historyApiFallback: {
disableDotRule: true
}
},
output: {
filename: 'js/[name].[hash].js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.ts$/,
loaders: ['awesome-typescript-loader', 'angular-router-loader']
},
{
test: /\.scss$/,
use: extractSass.extract({
use: [
{
loader: 'css-loader',
options: {
url: false,
import: true,
minimize: true,
sourceMap: true,
importLoaders: 1
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
],
fallback: 'style-loader'
})
}
]
},
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\/]node_modules[\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
}
};
最后这是我非常简单的测试:
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { DashboardComponent } from './dashboard.component';
describe('The Dashboard', () => {
let component: DashboardComponent;
let fixture: ComponentFixture<DashboardComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [DashboardComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(DashboardComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should be created', () => {
expect(component).toBeTruthy();
});
});
此应用在 npm start
时正常运行。我再次遇到的问题是 HTML 文件的 404。
ERROR: 'Unhandled Promise rejection:', 'Failed to load
views/components/dashboard/dashboard.component.html', '; Zone:',
'ProxyZone', '; Task:', 'Promise.then', '; Value:', 'Failed to load
views/components/dashboard/dashboard.component.html', undefined
我尝试覆盖 TestBed.configureTestingModule()
中的测试规范以在不同位置查找 HTML 文件。我尝试在 karma.config.js 中添加新的文件模式。我也尝试过将两者结合使用但没有成功。
我通过执行以下操作修复了它:
在 karma.config.js
我添加了这一行:
proxies: { "/dist/": 'http://localhost:8080' }
在规范文件中我添加了这个覆盖:
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [DashboardComponent]
}).overrideComponent(DashboardComponent, {
set: {
templateUrl: '/dist/views/components/dashboard/dashboard.component.html'
}
})
.compileComponents();
}));
我确实删除了 { pattern: 'dist/views/components/dashboard/dashboard.component.html', included: false, watched: true }
模式,因为它没有做任何有人在评论中指出的事情。
我们有一个使用 karma 进行单元测试的混合 Angular 应用程序。我正在尝试添加我们的第一套测试,但我收到一些错误,表明 karma 无法找到 dashboard.component.html
。
查看:
import { Component, OnInit } from '@angular/core';
@Component({
templateUrl: './views/components/dashboard/dashboard.component.html'
})
export class DashboardComponent implements OnInit {
constructor() {}
ngOnInit() {
console.log('works!');
}
}
这是我的 karma.config.js
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['angular', 'jasmine'],
files: [
{ pattern: 'src/test.ts', watched: false },
{ pattern: 'dist/views/components/dashboard/dashboard.component.html', included: false, watched: true }
],
exclude: [],
preprocessors: {
'src/test.ts': ['webpack', 'sourcemap']
},
webpack: require('./webpack-base.config'),
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
singleRun: true,
concurrency: Infinity,
browsers: ['Chrome_Headless'],
customLaunchers: {
Chrome_Headless: {
base: 'Chrome',
flags: [
'--headless',
'--disable-gpu',
'--remote-debugging-port=9222'
]
},
Chrome_without_security: {
base: 'Chrome',
flags: [
'--headless',
'--disable-gpu',
'--remote-debugging-port=9222',
'--disable-web-security'
]
}
},
// workaround for typescript and chrome/headless
mime: {
'text/x-typescript': ['ts', 'tsx']
}
});
};
我们的混合应用程序是使用 Webpack 编译的。所有视图文件都复制到 /view
。这是我们的 webpack 文件:
/* eslint-env node */
const webpack = require('webpack');
const helpers = require('./helpers');
const path = require('path');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const extractSass = new ExtractTextPlugin({
filename: 'css/[name].[hash].css',
disable: process.env.NODE_ENV === 'development'
});
module.exports = {
mode: 'development',
entry: {
app: './src/js/index.ts'
},
resolve: {
extensions: ['.ts', '.js', '.html'],
alias: {
'@angular/upgrade/static':
'@angular/upgrade/bundles/upgrade-static.umd.js'
}
},
plugins: [
new CleanWebpackPlugin(['dist']),
// Workaround for angular/angular#11580
new webpack.ContextReplacementPlugin(
// The (\|\/) piece accounts for path separators in *nix and Windows
/angular(\|\/)core(\|\/)@angular/,
helpers.root('./src'), // location of your src
{} // a map of your routes
),
new HtmlWebpackPlugin({
template: './src/index.html',
inject: 'body'
}),
new CopyWebpackPlugin([
{ from: './src/views', to: 'views' },
{ from: './src/js/components', to: 'views/components', ignore: ['*.ts', '*.scss']},
{ from: './src/img', to: 'img' },
{ from: './src/config.js', to: '' }
]),
extractSass
],
devtool: 'inline-source-map',
devServer: {
contentBase: './dist',
historyApiFallback: {
disableDotRule: true
}
},
output: {
filename: 'js/[name].[hash].js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.ts$/,
loaders: ['awesome-typescript-loader', 'angular-router-loader']
},
{
test: /\.scss$/,
use: extractSass.extract({
use: [
{
loader: 'css-loader',
options: {
url: false,
import: true,
minimize: true,
sourceMap: true,
importLoaders: 1
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
],
fallback: 'style-loader'
})
}
]
},
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\/]node_modules[\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
}
};
最后这是我非常简单的测试:
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { DashboardComponent } from './dashboard.component';
describe('The Dashboard', () => {
let component: DashboardComponent;
let fixture: ComponentFixture<DashboardComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [DashboardComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(DashboardComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should be created', () => {
expect(component).toBeTruthy();
});
});
此应用在 npm start
时正常运行。我再次遇到的问题是 HTML 文件的 404。
ERROR: 'Unhandled Promise rejection:', 'Failed to load views/components/dashboard/dashboard.component.html', '; Zone:', 'ProxyZone', '; Task:', 'Promise.then', '; Value:', 'Failed to load views/components/dashboard/dashboard.component.html', undefined
我尝试覆盖 TestBed.configureTestingModule()
中的测试规范以在不同位置查找 HTML 文件。我尝试在 karma.config.js 中添加新的文件模式。我也尝试过将两者结合使用但没有成功。
我通过执行以下操作修复了它:
在 karma.config.js
我添加了这一行:
proxies: { "/dist/": 'http://localhost:8080' }
在规范文件中我添加了这个覆盖:
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [DashboardComponent]
}).overrideComponent(DashboardComponent, {
set: {
templateUrl: '/dist/views/components/dashboard/dashboard.component.html'
}
})
.compileComponents();
}));
我确实删除了 { pattern: 'dist/views/components/dashboard/dashboard.component.html', included: false, watched: true }
模式,因为它没有做任何有人在评论中指出的事情。