【问题标题】:Can't bind to 'routerLink' since it isn't a known property of 'a'. ("<header id="header">无法绑定到“routerLink”,因为它不是“a”的已知属性。 ("<header id="header">
【发布时间】:2016-12-31 15:23:19
【问题描述】:

之前有人问过这个问题,我做了所有建议的 cmets,但似乎都没有。我有一个问题的组合。让 wallaby.js 与我的项目一起工作,并在我运行 ng test 时找出错误。

Can't bind to 'routerLink' since it isn't a known property of 'a'. ("<header id="header">                                                                                         <h1 id="logo">                                                                                                                                                                    <a [ERROR ->][routerLink]="['/home']"></a>                                                                                                        
                </h1>
        "): AppComponent@2:5
        Can't bind to 'routerLink' since it isn't a known property of 'a'. ("
                <div id="menu">
                        <a [ERROR ->][routerLink]="['/home']" class="btn">Home</a>
                        <a [routerLink]="['/about']" class="btn">About</a>
                        "): AppComponent@6:5
        Can't bind to 'routerLink' since it isn't a known property of 'a'. ("
                <div id="menu">
                        <a [routerLink]="['/home']" class="btn">Home</a>
                        <a [ERROR ->][routerLink]="['/about']" class="btn">About</a>
                        <a [routerLink]="['/experiments']" class="btn">Expe"): AppComponent@7:5
        Can't bind to 'routerLink' since it isn't a known property of 'a'. ("terLink]="['/home']" class="btn">Home</a>
                        <a [routerLink]="['/about']" class="btn">About</a>
                        <a [ERROR ->][routerLink]="['/experiments']" class="btn">Experiments</a>
                </div>
        "): AppComponent@8:5
        'router-outlet' is not a known element:
        1. If 'router-outlet' is an Angular component, then verify that it is part of this module.
        2. If 'router-outlet' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '@NgModule.schemas' of this component to suppress this message. ("
        <div id="container">
                [ERROR ->]<router-outlet></router-outlet>
        </div>
        "): AppComponent@18:1

我的 Ng 模块

import {BrowserModule} from "@angular/platform-browser";
import {NgModule,CUSTOM_ELEMENTS_SCHEMA} from "@angular/core";
import {FormsModule} from "@angular/forms";
import {HttpModule} from "@angular/http";
import {RouterModule} from "@angular/router";
import {HomeComponent} from "./home/home.component";
import {ExperimentsComponent} from "./experiments/experiments.component";
import {AboutComponent} from "./about/about.component";
import {AppComponent} from "./app.component";
import {ExperimentsService} from "./common/experiments.service";
import {StateService} from "./common/state.service";
import {ExperimentDetailComponent} from "./experiments/experiment-details/experiment.detail.component";

@NgModule({
    declarations: [
        AppComponent,
        AboutComponent,
        HomeComponent,
        ExperimentsComponent,
        ExperimentDetailComponent
    ],
    imports: [
        BrowserModule,
        FormsModule,
        HttpModule,
        RouterModule.forRoot([
            {path: '', redirectTo: '/home', pathMatch: 'full'},
            {path: 'home', component: HomeComponent},
            {path: 'about', component: AboutComponent},
            {path: 'experiments', component: ExperimentsComponent},
            {path: '**', component: HomeComponent}
        ])
    ],
    schemas: [
      CUSTOM_ELEMENTS_SCHEMA
    ],
    providers: [
        ExperimentsService,
        StateService
    ],
    bootstrap: [AppComponent]
})
export class AppModule {
}

这是唯一的模块。这是一个简单的应用程序:

我也在GitHub上发布了这个项目HERE

----------答案和解释如下------------

import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';
import {RouterTestingModule} from "@angular/router/testing";
import {HomeComponent} from "./home/home.component";
import {AboutComponent} from "./about/about.component";
import {ExperimentsComponent} from "./experiments/experiments.component";

describe('AppComponent', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule.withRoutes([
          {path: '', redirectTo: '/home', pathMatch: 'full'},
          {path: 'home', component: HomeComponent},
          {path: 'about', component: AboutComponent},
          {path: 'experiments', component: ExperimentsComponent},
          {path: '**', component: HomeComponent}
        ])
      ],
      declarations: [
        AppComponent
      ],
    });
    TestBed.compileComponents();
  });

  it('should create the app', async(() => {
    let fixture = TestBed.createComponent(AppComponent);
    let app = fixture.debugElement.componentInstance;
    expect(app).toBeTruthy();
  }));
});

但是现在我收到了Failed: Component HomeComponent is not part of any NgModule or the module has not been imported into your module. Error: Component HomeComponent is not part of any NgModule or the module has not been imported into your module.

但是 HomeCompenent 显然在我的@NgModule

【问题讨论】:

  • 请分享你的测试文件,你的ng测试没有使用这个文件
  • 我猜您需要将 RouterModule 添加到使用 routerLink 的测试文件中
  • AppModule 的内容与您的测试无关。您需要再次在 *.spec.ts-File 中导入(并声明)组件所需的所有内容
  • @benny_boe 请看我更新的帖子

标签: angular


【解决方案1】:

当您使用TestBed 时,您正在从头开始配置一个模块。在您当前的配置中,您所拥有的只是

TestBed.configureTestingModule({
  declarations: [
    AppComponent
  ],
});

因此,测试环境模块中包含的所有内容都是AppComponent。不包括 AppModule 中的任何内容。

所以您收到错误是因为您缺少 RouterModule 中包含的所有路由器指令。您可以导入RouterModule,但对于测试,您应该改用RouterTestingModule

import { RouterTestingModule } from '@angular/core/testing'

TestBed.configureTestingModule({
  imports: [
    RouterTestingModule.withRoutes([])
  ],
  declarations: [
    AppComponent
  ],
});

您可以将路由添加到withRoutes。

另请参阅:

【讨论】:

  • 请更新我的帖子。我认为你是对的一点,谢谢。
  • 请阅读我帖子的第一句话。这意味着您需要像在普通模块中一样添加测试所需的任何内容
  • 基本上,如果您将路由添加到RouterTestingModule,那么您需要声明与这些路由一起使用的相应组件
  • 用于测试,尽管您可能不想添加真正的组件。只需使用模拟组件。查看示例链接
【解决方案2】:

这是你的 app.component.spec.ts

你也应该在那里添加 routerModule

beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [
        AppComponent
      ],
      imports:[RouterModule.forRoot([])] //add the router module here as well
    });
    TestBed.compileComponents();
  });

当你测试你的 AppComponent 时,就像我说的那样,你应该给测试平台你给你的根 @NgModule 的东西,所以:

 beforeEach( () => {
    TestBed.configureTestingModule( {
        imports : [
            BrowserModule,
            FormsModule,
            HttpModule,
            RouterTestingModule.withRoutes( [
                { path : '', redirectTo : '/home', pathMatch : 'full' },
                { path : 'home', component : HomeComponent },
                { path : 'about', component : AboutComponent },
                { path : 'experiments', component : ExperimentsComponent },
                { path : '**', component : HomeComponent }
            ] )
        ],
        declarations : [
            AppComponent,
            AboutComponent,
            HomeComponent,
            ExperimentsComponent,
            ExperimentDetailComponent
        ],

        schemas : [
            CUSTOM_ELEMENTS_SCHEMA
        ],
        providers : [
            ExperimentsService,
            StateService
        ]
    } );
    TestBed.compileComponents();
} );

【讨论】:

  • 请看我的更新。这似乎也可以解决 routerLink 错误,但现在它说我的 HomeComponent 不在我的 @NgModule 中,但显然是。
  • @Drew1208 ,伙计,如果你要测试 app.component ,你应该定义你在 NgModule 中定义的所有内容
  • 你为什么不想测试你的 AppComponent,那真的很耗时,你应该做单元测试,测试整个应用更像是端到端测试
  • 你是绝对正确的。这就是我想要做的e2e。我仍然熟悉测试 Angular 2 测试。
【解决方案3】:

我也有这个问题,我用的是自建的模拟路由器。

使用/导入routing、router、 RouterTestingModule.withRoutes([]) 等的所有示例都给了我更多错误。

对我来说,解决方案也是为routerLink 指令创建一个模拟(当你不模拟路由器但使用RouterTestingModule 时,我不确定在哪里找到实现,可能在RouterTestingModule本身?)

所以事后看来,我本可以自己创建模拟,但正如他们所说“真正的 RouterLinkDirective 非常复杂,并且与 RouterModule 的其他组件和指令纠缠在一起。它需要具有挑战性的设置才能模拟和在测试中使用。”

我在 Angular 文档页面找到了它的实现:https://angular.io/guide/testing-components-scenarios#routerlink

由于链接可能会消失,因此我在此处发布代码:

@Directive({
  selector: '[routerLink]'
})
export class RouterLinkDirectiveStub {
  @Input('routerLink') linkParams: any;
  navigatedTo: any = null;

  @HostListener('click')
  onClick() {
    this.navigatedTo = this.linkParams;
  }
}

【讨论】:

    猜你喜欢
    • 2017-02-05
    • 2019-04-08
    • 2017-06-21
    • 2017-04-06
    • 2018-12-28
    • 1970-01-01
    • 2018-07-23
    • 1970-01-01
    • 2018-11-29
    相关资源
    最近更新 更多