gpt4 book ai didi

Angular Testing 错误 - 无法绑定(bind)到 'items',因为它不是 'app-dropdown' 的已知属性

转载 作者:行者123 更新时间:2023-12-03 14:25:22 24 4
gpt4 key购买 nike

只想说,我认识到有很多与“无法绑定(bind)到 X,因为它不是 Y 的已知属性”错误相关的 SO 帖子。我查看了很多,并找到了一些解决具体问题的答案,但是我很难将其转化为我的案例,我实际上认为这是很笼统的,并且与对的基本误解有关我应该如何解决我的用例。

我正在创建一个 Angular (7) 应用程序,我已将其分成 componentsroutes . components是模块化的部分(下拉菜单、模式、按钮等等),并且路由是应用程序中的各个页面。这个术语有点复杂,因为两者在技术上都是 Angular 组件。换句话说,结构(在 src/ 内)如下所示:

- app
- components
- dropdown
- dropdown.component.ts
- dropdown.component.html
- dropdown.component.scss
- dropdown.component.spec.ts
- routes
- library
- library.component.ts
- library.component.html
- library.component.scss
- library.component.spec.ts
...

所以我有一个 Library 路由,它只是一个 Angular 组件,它导入一个 Dropdown 组件,如下所示:
import { Component, OnInit } from '@angular/core';

import { DropdownComponent } from '../../components/dropdown/dropdown.component';

@Component({
selector: 'app-library',
templateUrl: './library.component.html',
styleUrls: ['./library.component.scss']
})
export class LibraryComponent implements OnInit {
pickItem($event) {
console.log($event.item, $event.index);
}

constructor() { }

ngOnInit() {}
}

相关的库 HTML 文件:
<div class="library row py4">
<h3 class="typ--geo-bold typ--caps mb5">Style Library</h3>

<div class="mb4" style="max-width: 35rem;">
<p class="typ--geo-bold typ--caps">Dropdowns</p>
<app-dropdown
[items]="['One', 'Two', 'Three']"
(pick)="pickItem($event)"
title="Default dropdown"
></app-dropdown>
<br />
<app-dropdown
[items]="['One', 'Two', 'Three']"
(pick)="pickItem($event)"
title="Inline dropdown"
class="dropdown--inline"
></app-dropdown>
</div>
</div>

下拉组件是一个基本组件,结构类似。除非被问到,否则我不会将其粘贴在这里,因为我不确定它是否会添加。 (可以说它确实接受 items 作为输入——与以下错误相关)。

这在浏览器中完美运行,并在生产中正确构建。

当我运行我的 library.components.spec.ts但是,测试时,我遇到了以下错误:
Failed: Template parse errors:
Can't bind to 'items' since it isn't a known property of 'app-dropdown'.
1. If 'app-dropdown' is an Angular component and it has 'items' input, then verify that it is part of this module.
2. If 'app-dropdown' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.
3. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component. ("
<p class="typ--geo-bold typ--caps">Dropdowns</p>
<app-dropdown
[ERROR ->][items]="['One', 'Two', 'Three']"
(pick)="pickItem($event)"
title="Default dropdown"

这是基本的库规范文件:
import { TestBed, async } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { LibraryComponent } from './library.component';

describe('LibraryComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule],
declarations: [LibraryComponent],
}).compileComponents();
}));

it('should create the component', () => {
const fixture = TestBed.createComponent(LibraryComponent);
const lib = fixture.debugElement.componentInstance;
expect(lib).toBeTruthy();
});
});

Library 组件和 Dropdown 组件都没有关联的模块。我的理解是,这个错误可能与我没有将 Dropdown 组件导入 Library 模块或其他东西有关,但是
  • 一)我不知道该怎么做,
  • B) 然后我不确定如何将该模块合并到整个应用程序中,并且
  • C) 除了让测试正常工作之外,我不确定它的值(value)是什么。

  • 有没有办法在不将这些组件转换为模块的情况下让测试工作?所有路由组件都应该是模块吗?

    编辑

    添加下拉组件(如果相关):
    <div
    class="dropdown"
    [ngClass]="{ open: open }"
    tab-index="-1"
    [class]="class"
    #dropdown
    >
    <div class="dropdown__toggle" (click)="onTitleClick(dropdown)">
    <span class="dropdown__title">{{ finalTitle() }}</span>
    <span class="dropdown__icon icon-arrow-down"></span>
    </div>
    <div *ngIf="open" class="dropdown__menu">
    <ul>
    <li
    *ngFor="let item of items; let ind = index"
    class="dropdown__item"
    [ngClass]="{ selected: selectedIndex === ind }"
    (click)="onItemClick(dropdown, item, ind)"
    >
    <span class="dropdown__label">{{ item }}</span>
    </li>
    </ul>
    </div>
    </div>

    和:
    import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';

    @Component({
    selector: 'app-dropdown',
    templateUrl: './dropdown.component.html',
    styleUrls: ['./dropdown.component.scss']
    })
    export class DropdownComponent implements OnInit {

    @Input() items: Array<string>;
    @Input() public selectedIndex: number = null;
    @Input() public title = 'Select one';
    @Input() public open = false;
    @Input() public class = '';

    @Output() pick = new EventEmitter();

    constructor() { }

    ngOnInit() {}

    finalTitle () {
    return typeof this.selectedIndex === 'number'
    ? this.items[this.selectedIndex]
    : this.title;
    }

    onItemClick(dropdown, item, index) {
    this._blur(dropdown);
    this.selectedIndex = index;
    this.open = false;
    this.pick.emit({ item, index });
    }

    onTitleClick(dropdown) {
    this._blur(dropdown);
    this.open = !this.open;
    }

    _blur(dropdown) {
    if (dropdown && dropdown.blur) { dropdown.blur(); }
    }
    }

    最佳答案

    更新以更清楚地回答您的 3 个问题

    一)有很多方法可以在不创建新模块的情况下完成此操作。您可以按照 André 下面的建议将 DropdownComponent 简单地导入您的测试模块。我在这个答案的下面概述了另一种方法,它 stub DropdownComponent,只是为了测试 LibraryComponent。希望这能回答“如何做到这一点”的问题。

    B) 我建议的 stub 不是一个模块——它甚至不是一个组件。没有必要将 stub 合并到整个应用程序中,它的唯一目的是测试 LibraryComponent。

    C) 此 stub 的值仅用于测试 LibraryComponent,这就是为什么让它尽可能简单是个好主意。

    这是在不将组件转换为模块的情况下让测试工作的一种方法。

    stub 下拉组件:

    下面是一种 stub 您尝试在 LibraryComponent 内部使用的 DropdownComponent 的方法。您在问题中详述的错误与您没有定义“app-dropdown”选择器这一事实直接相关,但您的 LibraryComponent 正试图绑定(bind)到它。假设您只想在 library.component.spec.ts 文件中测试 LibraryComponent,我建议将 DropdownComponent 功能 stub ,而不是将实际组件导入测试。我创建了一个 Stackblitz表明我的意思。

    来自 Stackblitz,这是 library.component.spec.ts 文件中的一个片段:

    @Component({
    selector: 'app-dropdown',
    template: `<h5>Dropdown</h5>`
    })
    class TestDropdownComponent {
    @Input() items;
    @Input() title;
    @Output() pick = new EventEmitter<any>();
    }

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

    beforeEach(async(() => {
    TestBed.configureTestingModule({
    imports: [ RouterTestingModule ],
    declarations: [
    TestDropdownComponent,
    LibraryComponent
    ]
    }).compileComponents();
    fixture = TestBed.createComponent(LibraryComponent);
    }));
    it('should create the component', () => {
    const fixture = TestBed.createComponent(LibraryComponent);
    const lib = fixture.debugElement.componentInstance;
    expect(lib).toBeTruthy();
    });
    });

    Note - If you want to reproduce the error you detail in your question within the Stackblitz, simply comment out the line for TestDropdownComponent in the declarations of the TestBed so it looks like so:


    TestBed.configureTestingModule({
    imports: [ RouterTestingModule ],
    declarations: [
    // TestDropdownComponent,
    LibraryComponent
    ]
    }).compileComponents();

    And you will once again be testing just your component without a mock/stub of DropdownComponent to bind to.

    关于 Angular Testing 错误 - 无法绑定(bind)到 'items',因为它不是 'app-dropdown' 的已知属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53345091/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com