我正在尝试为具有@Input属性的组件编写单元测试,该组件恰好包含带有[routerLink]的锚标记。
我遇到了错误:
Failed: Template parse errors: Can't bind to 'routerLink' since it isn't a known property of 'a'.
要解决此问题,我添加了RouterTestingModule
,现在出现此错误:
TypeError: Cannot read property '__source' of undefined
。
Component.ts
import {Component, Input, OnInit} from '@angular/core';
import {Tile, TileDefinition} from "../../model/tile";
import {TilesService} from "../../services/tiles.service";
import {Observable} from "rxjs";
@Component({
selector: 'app-tile',
templateUrl: './tile.component.html',
styleUrls: ['./tile.component.scss']
})
export class TileComponent implements OnInit {
@Input() tile: Tile;
percentComplete: string;
detailsExposed: boolean = false;
public tileDescription: Observable<TileDefinition>;
constructor(private tileService: TilesService) { }
ngOnInit() {
let num = parseInt(this.tile.custom3);
if(isNaN(num)){
this.percentComplete = '0%';
} else {
this.percentComplete = parseInt(this.tile.custom3).toString() + '%';
}
}
showDetails(): void {
this.detailsExposed = true;
this.tileDescription = this.tileService.getTileDefinition(this.tile.id);
}
hideDetails(): void {
this.detailsExposed = false;
}
}
Component.html
<div class="row no-gutters mx-1 py-2 border-bottom">
<div class="col-1">{{ tile.id }}</div>
<div class="col">{{ tile.name }}</div>
<div class="col-2">
<div class="form-row">
<div class="col">
<div class="progress">
<div class="progress-bar"
[ngClass]="{'bg-success': percentComplete == '100%'}"
[ngStyle]="{'width': percentComplete}">
{{percentComplete}}
</div>
</div>
</div>
<div class="col-auto">
<button class="btn btn-xs btn-light border text-primary show_more_button" *ngIf="!detailsExposed" (click)="showDetails()">More
</button>
<button class="btn btn-xs btn-light border text-primary show_less_button" *ngIf="detailsExposed" (click)="hideDetails()">Less
</button>
</div>
</div>
</div>
</div>
<div class="p-3 mx-1 border rounded-bottom bg-white" *ngIf="detailsExposed">
<ng-container *ngIf="tileDescription | async; else loading">
<a [routerLink]="['/fileeditor','tile',tile.id,'json','definitions']" class="btn btn-sm btn-info">Edit Configuration</a>
</ng-container>
<ng-template #loading>
<div class="col-12 text-center"><p class="display-4 text-muted">Loading</p></div>
</ng-template>
</div>
测试规范
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {TileComponent} from './tile.component';
import {TilesService} from "../../services/tiles.service";
import {Component, DebugElement, ViewChild} from "@angular/core";
import {Tile, TileDefinition} from "../../model/tile";
import {By} from "@angular/platform-browser";
import {RouterTestingModule} from "@angular/router/testing";
import {of} from "rxjs";
// mock a host container so we can input bind to the unit under test
@Component({
template: '<app-tile [tile]="tile"></app-tile>'
})
class HostComponent{
tile: Tile = {
id: "5",
name: "TileName",
custom3: "20% imaged"
};
@ViewChild(TileComponent) tileComponent: TileComponent;
}
describe('TileComponent', () => {
let component: HostComponent;
let fixture: ComponentFixture<HostComponent>;
let tilesServiceSpy: { getTileDefinition: jasmine.Spy }; // we'll use a spy in place of the real service
beforeEach(async(() => {
// create the spy to inject as a substitute for the real TileService
const tilesService = jasmine.createSpyObj('TilesService', ['getTileDefinition']);
TestBed.configureTestingModule({
declarations: [ HostComponent, TileComponent ],
providers: [{ provide: TilesService, useValue: tilesServiceSpy}],
imports: [RouterTestingModule.withRoutes([])]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(HostComponent);
component = fixture.componentInstance;
tilesServiceSpy = TestBed.get(tilesServiceSpy); // we want to get the 'real' instance from our env
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should set percentcomplete on init', () => {
expect(component.tileComponent.percentComplete).toBeUndefined('starts undefined');
fixture.detectChanges(); // ngOnInit
expect(component.tileComponent.percentComplete).toEqual('60%', 'set percentCompete on init')
});
});
答案 0 :(得分:1)
在这种情况下,您用于tilesServiceSpy = TestBed.get(tilesServiceSpy);
的行应改为tilesServiceSpy = TestBed.get(TilesService);
更改之后,您将可以继续。