无法对我的 Angular 4 代码运行简单的业力测试

Posted

技术标签:

【中文标题】无法对我的 Angular 4 代码运行简单的业力测试【英文标题】:Unable to run a simple karma test against my angular 4 code 【发布时间】:2020-10-28 09:20:02 【问题描述】:

我正在尝试对我的 Angular 4 组件进行最低限度的测试,但我根本无法让它工作。

我正在运行这个命令:karma start src/test/javascript/karma.conf.js

这是输出: Error: This test module uses the component AppComponent which is using a "templateUrl" or "styleUrls", but they were never compiled. Please call "TestBed.compileComponents" before your test.

这是我的 app.component.spec.ts 文件:

import  async, ComponentFixture, TestBed  from '@angular/core/testing';
import  AppComponent from "../../../../../main/webapp/app/admin/app";

describe('AppComponent (minimal)', () => 
    it('should create', () => 
        TestBed.configureTestingModule(
            declarations: [ AppComponent ]
        )
            .compileComponents();

        const fixture = TestBed.createComponent(AppComponent);
        const component = fixture.componentInstance;
        expect(component).toBeDefined();
    );
);

我只是想测试一下我在 app.component.ts 文件中创建的一些函数,也许还想测试一下 app.component.html 中的一些 HTML

这是我的 karma.conf.js 文件:

const webpackConfig = require('../../../webpack/webpack.test.js');

const ChromiumRevision = require('puppeteer/package.json').puppeteer.chromium_revision;
const Downloader = require('puppeteer/utils/ChromiumDownloader');
const revisionInfo = Downloader.revisionInfo(Downloader.currentPlatform(), ChromiumRevision);
process.env.CHROMIUM_BIN = revisionInfo.executablePath;

const WATCH = process.argv.indexOf('--watch') > -1;

module.exports = (config) => 
    config.set(

        // base path that will be used to resolve all patterns (eg. files, exclude)
        basePath: './',

        // frameworks to use
        // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
        frameworks: ['jasmine', 'intl-shim'],

        // plugins
        plugins: [
            require('karma-jasmine'),
            require('karma-junit-reporter'),
            require('karma-notify-reporter'),
            require('karma-chrome-launcher'),
            require('karma-remap-istanbul'),
            require('karma-sonarqube-reporter'),
            require('karma-webpack'),
            require('karma-sourcemap-loader'),
            require("karma-intl-shim")
        ],

        // list of files / patterns to load in the browser
        files: [
            'spec/entry.ts'
        ],


        // list of files to exclude
        exclude: ['e2e/**'],

        // preprocess matching files before serving them to the browser
        // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
        preprocessors: 
            'spec/entry.ts': ['webpack', 'sourcemap']
        ,

        webpack: webpackConfig(WATCH),

        // test results reporter to use
        // possible values: 'dots', 'progress'
        // available reporters: https://npmjs.org/browse/keyword/karma-reporter
        reporters: ['dots', 'junit', 'progress', 'karma-remap-istanbul', 'notify', 'sonarqube'],

        junitReporter: 
            outputFile: '../../../../target/test-results/karma/TESTS-results.xml'
        ,

        notifyReporter: 
            reportEachFailure: true, // Default: false, will notify on every failed sepc
            reportSuccess: true // Default: true, will notify when a suite was successful
        ,


        remapIstanbulReporter: 
            reports:  // eslint-disable-line
                'lcovonly': 'target/test-results/coverage/report-lcov/lcov.info',
                'html': 'target/test-results/coverage',
                'text-summary': null
            
        ,

        sonarqubeReporter: 
            //basePath: 'src/app',        // test files folder
            basePath: './',             // test files folder
            filePattern: '**/*spec.ts', // test files glob pattern
            encoding: 'utf-8',          // test files encoding
            outputFolder: 'target/test-results/karma',    // report destination - target/test-results/karma
            legacyMode: false,          // report for Sonarqube < 6.2 (disabled)
            reportName: 'karma-sonarqube-report.xml'
        ,

        // web server port
        port: 9876,

        // enable / disable colors in the output (reporters and logs)
        colors: true,

        // level of logging
        // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
        logLevel: config.LOG_INFO,

        // enable / disable watching file and executing tests whenever any file changes
        autoWatch: WATCH,

        // start these browsers
        // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
        browsers: ['ChromiumHeadlessNoSandbox'],

        customLaunchers: 
            ChromiumHeadlessNoSandbox: 
                base: 'ChromiumHeadless',
                flags: ['--no-sandbox']
            
        ,

        // Ensure all browsers can run tests written in .ts files
        mime: 
            'text/x-typescript': ['ts','tsx']
        ,

        // Continuous Integration mode
        // if true, Karma captures browsers, runs the tests and exits
        singleRun: !WATCH
    );
;

编辑:当我尝试使用此代码时:

describe('AppComponent', () => 
    let component: AppComponent;
    let fixture: ComponentFixture<AppComponent>;

    beforeEach(async(() => 
        TestBed.configureTestingModule(
            declarations: [ AppComponent]
        )
            .compileComponents();
    ));

    beforeEach(() => 
        fixture = TestBed.createComponent(AppComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
    );

    it('should create', () => 
        expect(component).toBeTruthy();
    );
);

我仍然遇到同样的错误,这是我的堆栈跟踪的更多内容:

  Error: Uncaught (in promise): Failed to load %3Cdiv%3E%0A%20%20%20%20%3Ch2%3E%0A%20%20%20%20%20%20%20%20%3Cspan%3EApplication%20Management%3C/span%3E%0A%20%20%20%20%20%20%20%20%3Cbutton%.....(lots and lots of "HTML" here)
            at resolvePromise (http://localhost:9877webpack:///node_modules/zone.js/dist/zone.js:783:0 <- spec/entry.ts:93156:31)
            at resolvePromise (http://localhost:9877webpack:///node_modules/zone.js/dist/zone.js:754:0 <- spec/entry.ts:93127:17)
            at http://localhost:9877webpack:///node_modules/zone.js/dist/zone.js:831:0 <- spec/entry.ts:93204:17
            at ZoneDelegate.invokeTask (http://localhost:9877webpack:///node_modules/zone.js/dist/zone.js:424:0 <- spec/entry.ts:92797:31)
            ...

        Error: This test module uses the component AppComponent which is using a "templateUrl" or "styleUrls", but they were never compiled. Please call "TestBed.compileComponents" before your test.
            at TestBed._initIfNeeded (http://localhost:9877webpack:///node_modules/@angular/core/@angular/core/testing.es5.js:756:0 <- spec/entry.ts:36698:27)
            at TestBed.createComponent (http://localhost:9877webpack:///node_modules/@angular/core/@angular/core/testing.es5.js:873:0 <- spec/entry.ts:36815:14)
            at Function.TestBed.createComponent (http://localhost:9877webpack:///node_modules/@angular/core/@angular/core/testing.es5.js:652:0 <- spec/entry.ts:36594:29)
            at UserContext.<anonymous> (http://localhost:9877webpack:///src/test/javascript/spec/app/admin/app.component.spec.ts:16:26 <- spec/entry.ts:80888:37)
            ...

        Expected undefined to be truthy.
            at UserContext.<anonymous> (http://localhost:9877webpack:///src/test/javascript/spec/app/admin/app.component.spec.ts:22:26 <- spec/entry.ts:80893:27)

我确实看到了关于我的 entry.ts 的讨论,这里是:

TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());

declare let require: any;
const testsContext: any = require.context('./', true, /\.spec/);
testsContext.keys().forEach(testsContext);

【问题讨论】:

【参考方案1】:

通常会调用测试台并在每次测试之前初始化组件/固定装置,而不是在每次测试中(通常)。

describe('AppComponent', () => 
  let component: AppComponent;
  let fixture: ComponentFixture<AppComponent>;

  beforeEach(async(() => 
    TestBed.configureTestingModule(
      declarations: [ AppComponent]
    )
    .compileComponents();
  ));

  beforeEach(() => 
    fixture = TestBed.createComponent(AppComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  );

  it('should create', () => 
    expect(component).toBeTruthy();
  );
);

【讨论】:

我刚刚编辑了我的帖子(请参阅“编辑:当我使用此代码尝试时:”)。我正在使用您的代码,但仍然出现相同的错误【参考方案2】:
import  ComponentFixture, TestBed, async  from '@angular/core/testing';
import  UiTestModule  from '../../../test.module';
import AccountService, Principal from "../../../../../../main/webapp/app/shared";
import DashboardService from "../../../../../../main/webapp/app/dashboard/dashboard.service";
import AppService from "../../../../../../main/webapp/app/admin/app";
import JhiEventManager, JhiParseLinks from "ng-jhipster";
import ActivatedRoute, Router from "@angular/router";
import ToasterAlertService from "../../../../../../main/webapp/app/shared/alert/toaster-alert.service";
import ToastOptions, ToastsManager from "ng2-toastr";
import  AppComponent from "../../../../../../main/webapp/app/admin/app";
import DomSanitizer from "@angular/platform-browser";
import Observable from "rxjs";

describe('AppComponent', () => 

    let comp: AppComponent;
    let fixture: ComponentFixture<AppComponent>;
    // let service: JhiHealthService;

    const fakeActivatedRoute = 
        snapshot:  data:   ,
     as ActivatedRoute;

    beforeEach(async(() => 
        TestBed.configureTestingModule(
            imports: [UiTestModule],
            declarations: [AppComponent],
            providers: [
                AppService,
                JhiParseLinks,
                Principal,
                
                    provide: ActivatedRoute,
                    useValue: 
                        data: 
                            // subscribe: (fn: (value: Data) => void) => fn(
                            subscribe: (fn: () => void) => fn(
                                // company: COMPANY,
                                pagingParams:  
                                    page: 1
                                
                            ),
                        ,
                        params: 
                            // subscribe: (fn: (value: Params) => void) => fn(
                            subscribe: (fn: () => void) => fn(
                                tab: 0,
                            ),
                        ,
                        snapshot: 
                            url: [
                                
                                    path: 'foo',
                                ,
                                
                                    path: 'bar',
                                ,
                                
                                    path: 'baz',
                                ,
                            ],
                        ,
                    ,
                ,
                 provide: Router, useValue: null ,
                JhiEventManager,
                DomSanitizer,
                ToasterAlertService,

                AccountService,
                ToastsManager,
                ToastOptions
            ]
        ).overrideTemplate(AppComponent, '')
        .compileComponents();
    ));

    beforeEach(() => 
        fixture = TestBed.createComponent(AppComponent);
        comp = fixture.componentInstance;
        // service = fixture.debugElement.injector.get(JhiHealthService);
    );

    describe('TODO3', () => 
        it('TODO4', () => 
            expect(comp.foo()).toEqual('bar');

        );
    );

);

【讨论】:

以上是关于无法对我的 Angular 4 代码运行简单的业力测试的主要内容,如果未能解决你的问题,请参考以下文章

使用业力和 webpack 4 运行单元测试时无法读取未定义的属性“externalModuleIndicator”

IntelliJ 中的业力:测试框架意外退出 [关闭]

Angular 8 业力忽略服务请求

Angular 2 业力设置问题——业力启动但不运行测试

测试可观察对象 Angular 2 业力

Angular 单元测试中业力代码覆盖率报告中的 1x 3x 等是啥意思?