Angular 组件方法的单元测试7
我的组件代码-Angular 组件方法的单元测试7,angular,unit-testing,karma-jasmine,angular7,Angular,Unit Testing,Karma Jasmine,Angular7,我的组件代码- import { Component, EventEmitter, Input, OnInit, OnChanges, SimpleChanges, Output } from '@angular/core'; import { CI, CiWithStatus } from '../ci-list.service'; import { ContextPanelApi } from '../../../../../../../../shared/shared-html/js/d
import { Component, EventEmitter, Input, OnInit, OnChanges, SimpleChanges, Output } from '@angular/core';
import { CI, CiWithStatus } from '../ci-list.service';
import { ContextPanelApi } from '../../../../../../../../shared/shared-html/js/directives/oprContextPanel/oprContextPanel/oprContextPanelApi.service';
@Component({
selector: 'opr-watchlist-cards',
templateUrl: './watchlist-cards.component.html',
styleUrls: ['./watchlist-cards.component.scss']
})
export class WatchlistCardsComponent implements OnInit, OnChanges {
@Input() ciList: CiWithStatus[];
@Input() itemWidth: number;
@Input() itemHeight: number;
@Input() zoomLevel: number;
@Output() onSelectedCisChanged: EventEmitter<CI[]> = new EventEmitter<CI[]>();
private _selectedItems: CI[] = [];
constructor(private _oprContextPanelApiService: ContextPanelApi) {
}
ngOnInit() {
console.debug('ciList', this.ciList);
}
ngOnChanges(changes: SimpleChanges): void {
if(changes.zoomLevel) {
this.zoomLevel = changes.zoomLevel.currentValue;
}
}
onItemClick(event: MouseEvent, ci: CI) {
if (event.ctrlKey) {
if (this.isSelected(ci)) {
this._selectedItems.splice(this._selectedItems.indexOf(ci), 1);
} else {
this._selectedItems.push(ci);
}
} else {
this._selectedItems = [ci];
}
this.onSelectedCisChanged.emit(this._selectedItems);
}
onItemRightClick(event: MouseEvent, ci: CI) {
const position = {left: event.clientX, top: event.clientY};
const contextPanelConfig = {
title: 'context menu dummy ' + ci.name,
position
};
const contextPanelPages = [];
this._oprContextPanelApiService.openContext(contextPanelConfig, contextPanelPages, () => {
});
return false; //prevent native browser context menu
}
isSelected(ci: CI) {
return this._selectedItems.includes(ci);
}
}
import{Component,EventEmitter,Input,OnInit,OnChanges,SimpleChanges,Output}来自“@angular/core”;
从“../CI list.service”导入{CI,CiWithStatus};
从“../../../../../../../../../shared/html/js/directives/oprContextPanel/oprContextPanel/oprContextPanelApi.service”导入{ContextPanelApi};
@组成部分({
选择器:“opr观察列表卡”,
templateUrl:“./watchlist cards.component.html”,
样式URL:['./监视列表卡.component.scss']
})
导出类WatchlistCardsComponent实现OnInit、OnChanges{
@Input()ciList:CiWithStatus[];
@Input()itemWidth:number;
@Input()itemHeight:数字;
@Input()zoomLevel:数字;
@SelectedCisChanged上的输出()为:EventEmitter=new EventEmitter();
private _selectedItems:CI[]=[];
构造函数(私有的OprContextPanelAPI服务:ContextPanelApi){
}
恩戈尼尼特(){
console.debug('ciList',this.ciList);
}
ngOnChanges(更改:SimpleChanges):无效{
if(changes.zoomLevel){
this.zoomLevel=changes.zoomLevel.currentValue;
}
}
onItemClick(事件:MouseEvent,ci:ci){
if(event.ctrlKey){
如果(本条被选为(ci)){
this.\u selectedItems.splice(this.\u selectedItems.indexOf(ci),1);
}否则{
此按钮。\u选择editems.push(ci);
}
}否则{
这._selectedItems=[ci];
}
this.onSelectedCisChanged.emit(this.\u selectedItems);
}
onItemRightClick(事件:MouseeEvent,ci:ci){
const position={left:event.clientX,top:event.clientY};
const contextPanelConfig={
标题:“上下文菜单虚拟”+ci.name,
位置
};
const contextPanelPages=[];
此.oprContextPanelApiService.openContext(contextPanelConfig,contextPanelPages,()=>{
});
返回false;//防止本机浏览器上下文菜单
}
当选(ci:ci){
返回此项。\u selectedItems.includes(ci);
}
}
我的规范文件代码-
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { SimpleChange } from '@angular/core';
import { WatchlistCardsComponent } from './watchlist-cards.component';
import { AppSharedModule } from '../../../../../app-shared/src/lib/app-shared.module';
import { WatchlistCardComponent } from './watchlist-card/watchlist-card.component';
import { ContextPanelApi } from 'shared/directives/oprContextPanel/oprContextPanel/oprContextPanelApi.service';
export class MockContextPanelApi {
}
describe('WatchlistCardsComponent', () => {
let component: WatchlistCardsComponent;
let fixture: ComponentFixture<WatchlistCardsComponent>;
let params;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [AppSharedModule],
declarations: [WatchlistCardComponent, WatchlistCardsComponent],
providers: [{ provide: ContextPanelApi, useClass: MockContextPanelApi }]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(WatchlistCardsComponent);
component = fixture.componentInstance;
params = {
ci: {
global_id: "9e76bafea39c49e786360baeb2551fd7",
icon: "/odb/icons/unix/unix_32.svg",
id: "9e76bafea39c49e786360baeb2551fd7",
last_changed: 1540465938749,
long_id: "1;;9e76bafea39c49e786360baeb2551fd7",
name: "srv0",
status: 0,
type: "unix",
type_label: "Unix",
event: "link"
},
event: {
}
};
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should call ngOnChanges', () => {
component.zoomLevel = 3;
component.ngOnChanges({
zoomLevel: new SimpleChange(null, component.zoomLevel, true)
});
fixture.detectChanges();
})
it('should call the onItemClick method', async(() => {
spyOn(component, 'onItemClick');
component.onItemClick(params.event, params.ci);
fixture.whenStable().then(() => {
expect(component.onItemClick).toHaveBeenCalled();
});
}));
it('should call the onItemRightClick method', async(() => {
spyOn(component, 'onItemRightClick');
component.onItemRightClick(params.event, params.ci);
expect(component.onItemRightClick).toHaveBeenCalled();
}));
it('should call the isSelected method', async(() => {
spyOn(component, 'isSelected');
component.isSelected(params.ci);
expect(component.isSelected).toHaveBeenCalled();
}));
});
从'@angular/core/testing'导入{async,ComponentFixture,TestBed};
从“@angular/core”导入{SimpleChange};
从“./watchlist cards.component”导入{WatchlistCardsComponent};
从“../../../../../app shared/src/lib/app shared.module”导入{AppSharedModule};
从“./watchlist-card/watchlist-card.component”导入{WatchlistCardComponent};
从“shared/directions/oprContextPanel/oprContextPanel/oprContextPanel/oprContextPanelApi.service”导入{ContextPanelApi};
导出类MockContextPanelApi{
}
描述('WatchlistCardsComponent',()=>{
let组件:WatchlistCardsComponent;
let夹具:组件夹具;
让params;
beforeach(异步(()=>{
TestBed.configureTestingModule({
导入:[AppSharedModule],
声明:[WatchlistCardComponent,WatchlistCardsComponent],
提供程序:[{提供:ContextPanelApi,使用类:MockContextPanelApi}]
})
.compileComponents();
}));
在每个之前(()=>{
fixture=TestBed.createComponent(WatchlistCardsComponent);
组件=fixture.componentInstance;
参数={
ci:{
全局_id:“9e76bafea39c49e786360baeb2551fd7”,
图标:“/odb/icons/unix/unix_32.svg”,
id:“9e76bafea39c49e786360baeb2551fd7”,
最后更改:1540465938749,
long_id:“1;;9e76bafea39c49e786360baeb2551fd7”,
名称:“srv0”,
状态:0,
键入:“unix”,
键入_标签:“Unix”,
事件:“链接”
},
活动:{
}
};
fixture.detectChanges();
});
它('应该创建',()=>{
expect(component.toBeTruthy();
});
它('应称为ngOnChanges',()=>{
component.zoomLevel=3;
component.ngOnChanges({
zoomLevel:新的SimpleChange(null,component.zoomLevel,true)
});
fixture.detectChanges();
})
它('应该调用onItemClick方法',异步(()=>{
spyOn(组件“onItemClick”);
component.onItemClick(params.event,params.ci);
fixture.whenStable()然后(()=>{
expect(component.onItemClick).toHaveBeenCalled();
});
}));
它('应该调用onItemRightClick方法',异步(()=>{
spyOn(组件“onItemRightClick”);
组件。单击鼠标右键(params.event,params.ci);
期望(component.onItemRightClick).toHaveBeenCalled();
}));
它('应该调用isSelected方法',异步(()=>{
spyOn(组件“isSelected”);
选择组件(参数ci);
expect(component.isSelected).tohavebeencall();
}));
});
我想涵盖函数,我试着在规范中这样做,但它仍然说函数没有涵盖
请指导我如何介绍isSelected、onItemRightClick和onItemClick方法的函数和语句
谢谢。原因是spyOn()
,它将用存根替换原始方法。在报纸上读一读。因此,当您调用component.onItemClick
时。您只是调用了间谍,而不是原始函数。因此没有代码覆盖
修复:spyOn(组件,'onItemClick')。和.callThrough()代码>。这在文件中也有解释
但是,在我看来,您编写的测试不是很有用。例如:
line 1: component.onItemClick(params.event, params.ci);
fixture.whenStable().then(() => {
line 2: expect(component.onItemClick).toHaveBeenCalled();
第1行
-您正在手动调用右键单击()上的
。由于您手动调用该函数,第2行
将始终为真。但是,IRL此函数将在右键单击/单击HTML中的元素时触发
您应该做的是获取组件引用,如(我没有测试此代码,它只是一个引用,我假设您有一个元素(按钮),它有一个onclick
):
let夹具:组件夹具;
const buttonEle:HTMLElement=fixture.nativeElement.querySelector('button');
spyOn(组件“onItemClick”);
按钮。单击();
fixture.whenStable()然后(()=>{
期望(component.onItemClick).toHaveBeenCalled()。。。
这将在组件函数上创建一个间谍(与您所做的相同),区别在于您没有被调用
let fixture: ComponentFixture<WatchlistCardsComponent>;
const buttonEle: HTMLElement = fixture.nativeElement.querySelector('button');
spyOn(component, 'onItemClick');
button.click();
fixture.whenStable().then(() => {
expect(component.onItemClick).toHaveBeenCalled(); ...