Jav*_*der 0 unit-testing karma-jasmine angular 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/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);
}
}
Run Code Online (Sandbox Code Playgroud)
我的规范文件代码 -
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();
}));
});
Run Code Online (Sandbox Code Playgroud)
我想涵盖这些功能,我尝试在规范中这样做,但它仍然说功能未涵盖。
请指导我如何涵盖 isSelected、onItemRightClick、onItemClick 方法的函数和语句
谢谢。
原因是spyOn(),它将用存根替换原始方法。在Jasmine Doc 中阅读有关间谍的内容。所以,当你调用component.onItemClick. 你只是在调用间谍而不是原始函数。因此没有代码覆盖。
修复: spyOn(component, 'onItemClick').and.callThrough();。这在文档中也有解释。
但是,IMO 您正在编写的测试并不是很有用。例如:
line 1: component.onItemClick(params.event, params.ci);
fixture.whenStable().then(() => {
line 2: expect(component.onItemClick).toHaveBeenCalled();
Run Code Online (Sandbox Code Playgroud)
line 1- 您正在手动调用onRightClick(). 因为您手动调用该函数, line 2将始终为真。但是,IRL 此功能将在 HTML 中右键单击/单击元素时触发。
您应该做的是获取组件参考(我没有测试过这段代码,它只是一个参考,我假设您有一个元素(按钮),其中有一个onclick):
let fixture: ComponentFixture<WatchlistCardsComponent>;
const buttonEle: HTMLElement = fixture.nativeElement.querySelector('button');
spyOn(component, 'onItemClick');
button.click();
fixture.whenStable().then(() => {
expect(component.onItemClick).toHaveBeenCalled(); ...
Run Code Online (Sandbox Code Playgroud)
这将在组件函数上创建一个间谍(与您所做的相同),不同之处在于您不是onItemClick手动调用,而是按钮单击会自动触发函数调用,因此无需手动调用 eventHandler。
| 归档时间: |
|
| 查看次数: |
6587 次 |
| 最近记录: |