我正在按角度运行单元测试,我想触发一个click事件,这是单击后的下拉列表,它会下拉一个客户编号列表。我想在单元测试中触发该事件,如果成功触发了该事件,我可以更新与单击按钮索引相对应的客户信息。我已附上必要的代码以供参考。请让我知道如何触发点击事件?
//template.html
<mat-menu #menuFilter="matMenu">
<button *ngFor="let customer of customers; let i = index" (click)="onCustomerChange(i)" mat-menu-item class="selectCustomerData">{{customer.licenseownerid}}</button>
</mat-menu>
//angular generated code
<div class="mat-menu-panel ng-trigger ng-trigger-transformMenu ng-tns-c10-1 mat-menu-after
mat-menu-below ng-star-inserted mat-elevation-z2" role="menu" tabindex="-1" ng-reflect-klass="mat-menu-panel"
ng-reflect-ng-class="[object Object]" style="transform-origin: left top;">
<div class="mat-menu-content">
<button class="selectCustomerData mat-menu-item ng-star-inserted" mat-menu-item="" role="menuitem" tabindex="0" aria-disabled="false">0LPT_id0306
<div class="mat-menu-ripple mat-ripple" matripple="" ng-reflect-disabled="false" ng-reflect-trigger="[object HTMLButtonElement]">
</div>
</button>
<button class="selectCustomerData mat-menu-item ng-star-inserted" mat-menu-item="" role="menuitem" tabindex="0" aria-disabled="false">0LPT_id03061
<div class="mat-menu-ripple mat-ripple" matripple="" ng-reflect-disabled="false" ng-reflect-trigger="[object HTMLButtonElement]">
</div>
</button>
</div>
...and so on
</div>
//component.ts
onCustomerChange(i) {
this.customerNumber = this.customers[i].licenseownerid;
this.customerName = this.customers[i].licenseownername;
}
答案 0 :(得分:0)
我想提供有关我的问题的更多信息
<button mat-button [matMenuTriggerFor]="menuFilter" class="selectCustomer">
<span flex>{{customerNumber}}</span>
<mat-icon class="list-icon">expand_more</mat-icon>
</button> ------> event number 1
<mat-menu #menuFilter="matMenu">
<button *ngFor="let customer of customers; let i = index" (click)="onCustomerChange(i)"
mat-menu-item class="selectCustomerData">{{customer.licenseownerid}}</button>
</mat-menu> -----> event number 2
事件1单击一个按钮将触发事件2,在事件2中,许多按钮显示为下拉菜单。单击任何特定按钮时,将使用相应的按钮索引调用onCustomerchange方法。
主要问题是与事件2对应的所有元素都动态出现和消失。那么,在编写测试时,如何选择一个元素并为其触发事件呢?
答案 1 :(得分:0)
由于第一事件是一个有角度的物质事件,因此我可能会假设点击事件触发了菜单,并且不会在测试用例中包含该特定事件。
我宁愿在测试设置中使用NO_ERRORS_SCHEMA并仅触发您自己的按钮的点击事件:
spec.ts看起来像这样:
@Directive({
selector: 'mat-menu',
exportAs: 'matMenu'
})
class DirectiveStub {
}
describe('AppComponent', () => {
let component: AppComponent;
let fixture: ComponentFixture<AppComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [AppComponent, DirectiveStub],
schemas: [NO_ERRORS_SCHEMA]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
});
it('should be created', () => {
fixture.detectChanges();
expect(component).toBeTruthy();
});
it('click on second button', fakeAsync(() => {
component.customers = [
{licenseownerid: 'ID_1', licenseownername: 'NAME_1'},
{licenseownerid: 'ID_2', licenseownername: 'NAME_2'}
]
fixture.detectChanges();
const buttonDebugElems: DebugElement[] = fixture.debugElement.queryAll(By.css('button'));
expect(buttonDebugElems.length).toEqual(3);
buttonDebugElems[2].triggerEventHandler('click', null);
tick();
expect(component.customerName).toEqual('NAME_2');
expect(component.customerNumber).toEqual('ID_2');
}));
});
重要提示
不幸的是,有必要将指令角材料用于其菜单。那是spec文件顶部的空(未导出)指令。如果您要测试的菜单中有更多组件,建议将该指令移至位于单独文件夹内的单个文件中,例如'test',因此您可以在测试中重用该指令,但不会捆绑到您的应用程序中。
这是一个有效的示例:stackblitz