【问题标题】:The template specified for component AppComponent is not a string with Jest unit testing为组件 AppComponent 指定的模板不是带有 Jest 单元测试的字符串
【发布时间】:2021-08-07 17:34:29
【问题描述】:

我知道以前有人问过这个问题。我已经尝试了每个建议中的几乎所有内容。我正在尝试从 wijmo 运行这个测试应用程序,并结合了笑话。该网站运行良好,除了 css 没有完全通过,但并不担心。我只需要一个具有 wijmo 工作和 jest 作为单元测试框架的测试应用程序。添加 jest 后.. 当我使用 npm test 时收到错误。

package.json

 {
  "name": "test-app",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "jest --transformIgnorePatterns \"node_modules/(?!@test-app)/\" --env=jsdom",
    "test:coverage": "jest --coverage",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "~11.0.0",
    "@angular/common": "~11.0.0",
    "@angular/compiler": "~11.0.0",
    "@angular/core": "~11.0.0",
    "@angular/forms": "~11.0.0",
    "@angular/platform-browser": "~11.0.0",
    "@angular/platform-browser-dynamic": "~11.0.0",
    "@angular/router": "~11.0.0",
    "@grapecity/wijmo": "^5.20211.781",
    "@grapecity/wijmo.angular2.core": "^5.20211.781",
    "@grapecity/wijmo.angular2.grid": "^5.20211.781",
    "@grapecity/wijmo.angular2.grid.detail": "^5.20211.781",
    "@grapecity/wijmo.angular2.grid.filter": "^5.20211.781",
    "@grapecity/wijmo.angular2.input": "^5.20211.781",
    "@grapecity/wijmo.grid": "^5.20211.781",
    "bootstrap": "^5.0.1",
    "raw-loader": "^4.0.2",
    "rxjs": "~6.6.0",
    "tslib": "^2.0.0",
    "zone.js": "~0.10.2"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.1100.0",
    "@angular/cli": "~11.0.0",
    "@angular/compiler-cli": "~11.0.0",
    "@babel/preset-env": "^7.14.2",
    "@types/jest": "^26.0.23",
    "@types/node": "^12.20.13",
    "codelyzer": "^6.0.0",
    "jest": "^26.6.3",
    "jest-canvas-mock": "^2.3.1",
    "jest-preset-angular": "^8.4.0",
    "karma-coverage": "~2.0.3",
    "protractor": "~7.0.0",
    "ts-node": "~8.3.0",
    "tslint": "~6.1.0",
    "typescript": "~4.0.2"
  },
  "jest": {
    "preset": "jest-preset-angular",
    "setupFilesAfterEnv": [
      "<rootDir>/setup-jest.ts"
    ],
    "testPathIgnorePatterns": [
      "<rootDir>/node_modules/",
      "<rootDir>/dist/"
    ]
  }
}

app.module.ts

    
import { BrowserModule } from '@angular/platform-browser';
import { enableProdMode, NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { WjInputModule } from '@grapecity/wijmo.angular2.input';
import { WjGridModule } from '@grapecity/wijmo.angular2.grid';
import { FormsModule } from '@angular/forms';
import { DataService } from './app.data';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

@NgModule({
  declarations: [
    AppComponent
  ],
  providers: [DataService],
  imports: [WjInputModule, WjGridModule, BrowserModule, FormsModule],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.html

<div class="container-fluid">
    <p>
        Use an <b>ng-template</b> element with the <b>wjFlexGridCellTemplate</b> directive
        to define a cell template.
        The content of the <b>ng-template</b> element defines the cell content.
        The <b>cellType</b> property specifies the type of the cells represented by the template.
        The <b>cell</b> local template variable contains an object with cell specific data,
        including the data item (<b>item</b>), row (<b>row</b>) and column (<b>col</b>) that
        the cell represents.
    </p>
    <p>
        Note that column-specific templates should be defined as children of
        the corresponding <b>wj-flex-grid-column</b> component, while the others
        are defined under the <b>wj-flex-grid</b> element.
    </p>
    <wj-flex-grid #grid [itemsSource]="data" [allowSorting]="false" [autoSizeMode]="'Both'" [allowResizing]="'Both'"
        [deferResizing]="true">

        <ng-template wjFlexGridCellTemplate [cellType]="'TopLeft'" *ngIf="customTopLeft">
            №
        </ng-template>
        <ng-template wjFlexGridCellTemplate [cellType]="'BottomLeft'" *ngIf="customBottomLeft">
            &#931;
        </ng-template>
        <ng-template wjFlexGridCellTemplate [cellType]="'RowHeader'" *ngIf="customRowHeader" let-cell="cell">
            {{cell.row.index + 1}}
        </ng-template>
        <ng-template wjFlexGridCellTemplate [cellType]="'RowHeaderEdit'" *ngIf="customRowHeaderEdit">
            ...
        </ng-template>

        <wj-flex-grid-column header="Country" binding="country" width="*">
            <ng-template wjFlexGridCellTemplate [cellType]="'Cell'" *ngIf="customCell" let-cell="cell">
                <img src="/dist/TestApp/assets/{{cell.item.country}}.png" />
                {{cell.item.country}}
            </ng-template>
            <ng-template wjFlexGridCellTemplate [cellType]="'CellEdit'" *ngIf="customCellEdit" let-cell="cell">
                <wj-combo-box [itemsSource]="countries" class="cell-editor" [(selectedValue)]="cell.value"
                    [isEditable]="false" [isRequired]="false" [placeholder]="'Select a Country'">
                </wj-combo-box>
            </ng-template>
            <ng-template wjFlexGridCellTemplate [cellType]="'GroupHeader'" *ngIf="customGroupHeader" let-cell="cell">
                <input type="checkbox" [(ngModel)]="cell.row.isCollapsed" />
                {{cell.item.name}} ({{cell.item.items.length}} items)
            </ng-template>
        </wj-flex-grid-column>

        <wj-flex-grid-column header="Downloads" binding="downloads" [width]="170" [aggregate]="'Sum'">
            <ng-template wjFlexGridCellTemplate [cellType]="'ColumnHeader'" *ngIf="customColumnHeader">
                <input type="checkbox" [(ngModel)]="highlightDownloads" />
                Downloads
            </ng-template>
            <ng-template wjFlexGridCellTemplate [cellType]="'Cell'" *ngIf="customCell" let-cell="cell">
                <span [ngStyle]="{color: highlightDownloads? (cell.item.downloads>10000 ?'green':'red'):''}"
                    style="font-weight:700">
                    {{cell.item.downloads}}
                </span>
            </ng-template>
            <ng-template wjFlexGridCellTemplate [cellType]="'CellEdit'" *ngIf="customCellEdit" let-cell="cell">
                <wj-input-number class="cell-editor" [(value)]="cell.value" [step]="1"></wj-input-number>
            </ng-template>
            <ng-template wjFlexGridCellTemplate [cellType]="'Group'" *ngIf="customGroup" let-cell="cell">
                Sum = {{cell.value | number:'1.0-0'}}
            </ng-template>
            <ng-template wjFlexGridCellTemplate [cellType]="'ColumnFooter'" *ngIf="customColumnFooter" let-cell="cell">
                Sum: {{cell.value | number:'1.0-0'}}
            </ng-template>
        </wj-flex-grid-column>
    </wj-flex-grid>

    <div class="checkbox-list">
        <div class="checkbox-list-title">Column level templates:</div>
        <div class="checkbox-cell">
            <label class="checkbox">
                <input type="checkbox" [(ngModel)]="customCell" /> Cell
            </label>
            <label class="checkbox">
                <input type="checkbox" [(ngModel)]="customCellEdit" /> CellEdit
            </label>
        </div>
        <div class="checkbox-cell">
            <label class="checkbox">
                <input type="checkbox" [(ngModel)]="customColumnHeader" /> ColumnHeader
            </label>
            <label class="checkbox">
                <input type="checkbox" [(ngModel)]="customColumnFooter" /> ColumnFooter
            </label>
        </div>
        <div class="checkbox-cell">
            <label class="checkbox">
                <input type="checkbox" [(ngModel)]="customGroupHeader" /> GroupHeader
            </label>
            <label class="checkbox">
                <input type="checkbox" [(ngModel)]="customGroup" /> Group
            </label>
        </div>

        <div class="checkbox-list-title">Grid level templates:</div>
        <div class="checkbox-cell">
            <label class="checkbox">
                <input type="checkbox" [(ngModel)]="customTopLeft" /> TopLeft
            </label>
            <label class="checkbox">
                <input type="checkbox" [(ngModel)]="customBottomLeft" /> BottomLeft
            </label>
        </div>
        <div class="checkbox-cell">
            <label class="checkbox">
                <input type="checkbox" [(ngModel)]="customRowHeader" /> RowHeader
            </label>
            <label class="checkbox">
                <input type="checkbox" [(ngModel)]="customRowHeaderEdit" /> RowHeaderEdit
            </label>
        </div>
    </div>
  </div>
  <router-outlet></router-outlet>
 

jest.config.js

const { pathsToModuleNameMapper } = require('ts-jest/utils');
const { compilerOptions } = require('./tsconfig');

module.exports = {
  preset: 'jest-preset-angular',
  roots: ['<rootDir>/src/'],
  testMatch: ['**/+(*.)+(spec).+(ts)'],
  setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
  setupFiles:["jest-canvas-mock"],
  collectCoverage: true,
  collectCoverageFrom: [
    '<rootDir>/src/**/*.ts',
    '!<rootDir>/src/**/*.interface.ts',
    '!<rootDir>/src/**/*.mock.ts',
    '!<rootDir>/src/**/*.module.ts',
    '!<rootDir>/src/**/*.spec.ts',
    '!<rootDir>/src/**/*.test.ts',
    '!<rootDir>/src/**/*.d.ts',
    '!<rootDir>/src/**/*.html',
    '!<rootDir>/src/**/*.css',    
    '!<rootDir>/src/polyfills.ts',
    '!<rootDir>/src/main.ts'
],
  coverageReporters: ["text","lcov","json","text","clover","cobertura"],
  coverageDirectory: 'coverage/test-app',
  moduleNameMapper: {'\\.(css|less)$': '<rootDir>/styleMock.js'}    
};

app.component.ts


import 'bootstrap/dist/css/bootstrap.css';
import '@grapecity/wijmo.styles/wijmo.css';
//
import { Component, Inject, ViewChild } from '@angular/core';
//
import * as wjcCore from '@grapecity/wijmo';
import * as wjcGrid from '@grapecity/wijmo.grid';
import { WjInputModule } from '@grapecity/wijmo.angular2.input';
import { WjGridModule } from '@grapecity/wijmo.angular2.grid';
import { DataService } from './app.data';
//
@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['../styles.scss']
})
export class AppComponent {
    countries: string[];
    data: wjcCore.CollectionView;
    customTopLeft = true;
    customRowHeader = true;
    customRowHeaderEdit = true;
    customCell = true;
    customCellEdit = true;
    customColumnHeader = true;
    customGroupHeader = true;
    customGroup = true;
    customColumnFooter = true;//
    customBottomLeft = true;
    highlightDownloads = true;
    //
    @ViewChild('grid', { static: true }) grid: wjcGrid.FlexGrid;
    title: any;
    //
    constructor(@Inject(DataService) dataSvc: DataService) {
        this.countries = dataSvc.getCountries();
        this.data = dataSvc.getCv(dataSvc.getData());

    }
    //
    ngAfterViewInit() {
        if (this.grid) {
            this.grid.columnFooters.rows.push(new wjcGrid.GroupRow());
        }
    }
}

AppComponent is not a string

【问题讨论】:

  • 我做对了吗问题是你在运行ng test 时没有任何样式?你能分享错误信息吗?
  • 问题是我在添加 jest 时收到此错误“为组件 AppComponent 指定的模板不是字符串”。我没有得到正确的样式。但这对我来说真的不关心。我只需要进行测试。在我的描述中添加错误。错误是链接“AppComponent 不是字符串”
  • 你能附上AppComponent@Component装饰师吗?它长什么样子?
  • 是的..应该这样做..我已经添加了它。
  • 抱歉放错了app.component.ts。现在已经修复了。

标签: angular unit-testing jestjs


【解决方案1】:

在我的情况下,我通过删除 "module": "commonjs" 条目错误配置了 tsconfig.spec.json。阅读它解决了这个问题。

【讨论】:

    猜你喜欢
    • 2019-09-02
    • 1970-01-01
    • 2023-03-13
    • 2018-06-03
    • 2019-05-28
    • 2021-04-23
    • 2017-11-18
    • 1970-01-01
    • 2019-11-28
    相关资源
    最近更新 更多