Angular 测试平台 - Karma/Jasmine |导入了意外值 'BrowserDynamicTestingModule' | Angular 奥特

Angular TestBed - Karma/Jasmine | Unexpected value imported 'BrowserDynamicTestingModule' | Angular AOT

测试床代码示例,遵循指南https://angular.io/guide/testing -

describe("Login", () => {
  let loginService: LoginService;

  beforeEach(() => {
    TestBed.configureTestingModule(
        { providers: [LoginService] }
    );

    loginService = TestBed.get(LoginService); // ERROR
  });

  it("login testing", (done: DoneFn) => {}); // Empty test
}

抛出错误-

        Error: Unexpected value 'BrowserDynamicTestingModule' imported by the module 'DynamicTestModule'. Please add a @NgModule annotation.
        at syntaxError (webpack-internal:///1394:723:34)
        at eval (webpack-internal:///1394:15544:48)
        at Array.forEach (<anonymous>)
        at CompileMetadataResolver.getNgModuleMetadata (webpack-internal:///1394:15519:53)
        at JitCompiler._loadModules (webpack-internal:///1394:34773:74)
        at JitCompiler._compileModuleAndAllComponents (webpack-internal:///1394:34751:40)
        at JitCompiler.compileModuleAndAllComponentsSync (webpack-internal:///1394:34639:46)
        at CompilerImpl.compileModuleAndAllComponentsSync (webpack-internal:///1409:264:58)
        at TestingCompilerImpl.compileModuleAndAllComponentsSync (webpack-internal:///1408:333:35)
        at TestBed._initIfNeeded (webpack-internal:///1393:998:36)
        at TestBed.get (webpack-internal:///1393:1069:14)
        at Function.TestBed.get (webpack-internal:///1393:854:29)
        at Object.eval (webpack-internal:///1413:10:42)
        at ZoneDelegate.invoke (webpack-internal:///781:392:26)
        at ProxyZoneSpec.onInvoke (webpack-internal:///1403:81:43)
        at ZoneDelegate.invoke (webpack-internal:///781:391:32)
        at Zone.run (webpack-internal:///781:142:43)
        at Object.eval (webpack-internal:///1405:96:38)
        at ZoneQueueRunner.jasmine.QueueRunner.ZoneQueueRunner.execute (webpack-internal:///1405:126:46)
        at ZoneQueueRunner.jasmine.QueueRunner.ZoneQueueRunner.execute (webpack-internal:///1405:126:46)
        at eval (webpack-internal:///1405:123:134)
        at ZoneDelegate.invokeTask (webpack-internal:///781:425:31)
        at Zone.runTask (webpack-internal:///781:192:47)
        at drainMicroTaskQueue (webpack-internal:///781:602:35)

Karma 配置文件 -

var webpackConfig = require('./config/webpack.test');

module.exports = function (config) {
var _config = {
    basePath: '',

    frameworks: ['jasmine'],

    files: [
      { pattern: './karma-test-shim.js', watched: false }
    ],

    preprocessors: {
        './karma-test-shim.js': ['webpack', 'sourcemap']
    },

    webpack: webpackConfig,

    webpackMiddleware: {
        logLevel: 'warn',
        stats: 'errors-only',
        chunks: false
    },

    webpackServer: {
        noInfo: true
    },

    reporters: ['progress'],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: false,
    browsers: ['ChromeHeadless'],
    singleRun: false,
    concurrency: Infinity
};

config.set(_config);
};

业力垫片 -

Error.stackTraceLimit = Infinity;
require('core-js/es6');
require('core-js/es7/reflect');
require('zone.js/dist/zone');
require('zone.js/dist/long-stack-trace-zone');
require('zone.js/dist/proxy');
require('zone.js/dist/sync-test');
require('zone.js/dist/jasmine-patch');
require('zone.js/dist/async-test');
require('zone.js/dist/fake-async-test');

// setup angular test bed
var testing = require('@angular/core/testing');
var browser = require('@angular/platform-browser-dynamic/testing');
testing.TestBed.initTestEnvironment(browser.BrowserDynamicTestingModule,                             
browser.platformBrowserDynamicTesting());

// setup app context
var appContext = require.context('./scripts', true, /\.spec\.ts/);
appContext.keys().forEach(appContext);

Webpack 开发-

// remove common chunks which can cause an issue for unit testing - jsonP
const commonsChunkPluginIndex = commonConfig.plugins.findIndex(plugin => 
plugin.chunkNames);
commonConfig.plugins.splice(commonsChunkPluginIndex, 1);

module.exports = webpackMerge(commonConfig, {
devtool: "cheap-module-eval-source-map",

output: {
    path: helpers.root("wwwroot"),
    filename: "[name].js",
    chunkFilename: "[id].chunk.js"
},

plugins: [
  new ExtractTextPlugin("[name].css")
],

devServer: {
    historyApiFallback: true,
    stats: "minimal"
}
});

Webpack 通用配置 -

module.exports = {
entry: {
    'polyfills': './scripts/polyfills.ts',
    'vendor': './scripts/vendor.ts',
    'app': './scripts/boot.ts'
},

resolve: {
    extensions: ['.ts', '.js']
},

module: {
    rules: [
      {
          test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
          loader: '@ngtools/webpack'
      },
      {
          test: /\.js$/,
          loader: '@angular-devkit/build-optimizer/webpack-loader',
          options: {
            sourceMap: false
          }
      },
      {
          test: /\.html$/,
          loader: 'html-loader',
          query: {
              interpolate: 'require'
          }
      },
      {
          test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
          use: [
              {
                  loader: 'url-loader',
                  options: {
                      limit: 100000
                  }
              }
          ]
      },
      {
          test: /\.scss$/,
          loaders: ['style-loader', 'css-loader', 'resolve-url-loader', 'sass-loader?sourceMap']
      },
      {
          test: /\.css$/,
          exclude: helpers.root('scripts', 'Components'),
          loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader?sourceMap' })
      },
      {
          test: /\.css$/,
          include: helpers.root('scripts', 'Components'),
          loader: 'raw-loader'
      }
    ]
},

plugins: [
    new webpack.optimize.CommonsChunkPlugin({
        name: ['app', 'vendor', 'polyfills']
    }),

    new HtmlWebpackPlugin({
        template: './wwwroot/index.html'
    }),

    new webpack.ProvidePlugin({
        $: 'jquery',
        jQuery: 'jquery',
        "window.jQuery": "jquery"
    }),

    new PurifyPlugin(),

    new AotPlugin({
        tsConfigPath: './tsconfig.json',
        entryModule: './scripts/app.module#AppModule',
        mainPath: './scripts/boot.ts',
        sourceMap: true
    })
]
};

Boot.ts 因为它是唯一包含与 BrowserDynamicTestingModule 相关的任何其他文件 -

import { enableProdMode }           from "@angular/core";
import { platformBrowserDynamic }   from "@angular/platform-browser-dynamic";
import { AppModule }                from "./app.module";
import { isProd, isCordova }        from "../globalFn";

if (isProd()) {
    enableProdMode();
}

// mobile app (TODO) must wait for the device to be ready before starting up
if (isCordova()) {
    document.addEventListener("deviceready", () => {
        platformBrowserDynamic().bootstrapModule(AppModule);
    }, false);
}
else {
    platformBrowserDynamic().bootstrapModule(AppModule);
}

我目前正在 运行宁 Angular AOT 5.2.0。我试过恢复到 JIT 构建,但得到了完全相同的错误。已经坚持了一段时间,现在任何关于导致这种情况的帮助或见解将不胜感激。

我可以正常编译和运行构建

我放弃了让 AOT 工作,也许有人知道这是否可能。我只是完全求助于 JIT 构建来进行测试。由于 awesome-ts-loader 已更新,JIT 构建之前无法正常工作。