Reputation: 2729
I am running unit test on angular app, When I click on dropdown, it should respond by updating front end data like id number
Frontend-template
<mat-menu #menuFilter="matMenu">
<button *ngFor="let customer of customers; let i = index"
(click)="onCustomerChange(i)" mat-menu-item class="selectCustomerData">
{{owner.id}}</button>
</mat-menu>
Backend-typescript
onCustomerChange(i) {
console.log(this.customers[i].ownerid);
this.customerNumber = this.customers[i].ownerid;
this.customerName = this.customers[i].ownername;
}
Test to be run
it('should update the customer number on selecting a value from drop down',()=>{
fixture.detectChanges();
//what should I do here
})
Upvotes: 2
Views: 9558
Reputation: 1073
This has bit of work to do.
First you have to put a id
to your buttons of your mat-menu
to identify by the querySelector
. Here I'm using index
with some string concatenation. Make your own logic and follow it in the spec file. Here I've also changed {{owner.id}}
to {{customer.ownerid}}
, since I don't know what owner.id is refer to and It doesn't relate to the answer. Also I've added button to trigger the menu since you haven't mentioned how to do so.
<mat-menu #menuFilter="matMenu">
<button *ngFor="let customer of customers; let i = index" [id]="'btn_'+i"
(click)="onCustomerChange(i)" mat-menu-item class="selectCustomerData">
{{customer.ownerid}}</button>
</mat-menu>
<!-- Refer to the spec.ts how to trigger this, since I don't know your logic.-->
<button mat-icon-button [matMenuTriggerFor]="menuFilter" id="btnMenu">
Click Here to Trigger the Menu
</button>
Now the spec.ts
let dom;
let button;
beforeEach(() => {
fixture = TestBed.createComponent(YourComponent);
component = fixture.componentInstance;
// You can initialize these here, if you are planning to use it inside the multiple
// test cases
dom = fixture.nativeElement;
button = dom.querySelector('#btnMenu');
fixture.detectChanges();
});
it('should update the customer number on selecting a value from drop down', () => {
// initially no mat-menu is opened
let menu = dom.parentNode.querySelector('.mat-menu-panel');
expect(menu).toBeFalsy();
// trigger the menu
button.click();
// mat menu should be open now
menu = dom.parentNode.querySelector('.mat-menu-panel');
expect(menu).toBeTruthy();
// click on the first element of the menu,it should pass the 0 index to the
// onCustomerChange method
dom.parentNode.querySelector('#btn_0').click();
expect(component.customerNumber).toBe(component.customers[0].ownerid);
});
You can implement this as 3 different test cases as well. Hope you've got the idea.!
Enjoy!!
Upvotes: 1
Reputation: 17514
Ok, first of all, a code improvement:
<mat-menu #menuFilter="matMenu">
<button *ngFor="let customer of customers"
(click)="onCustomerChange(customer)" mat-menu-item class="selectCustomerData">
{{owner.id}}</button>
</mat-menu>
and in ts:
onCustomerChange(customerObj) {
console.log(customerObj.ownerid);
this.customerNumber = customerObj.ownerid;
this.customerName = customerObj.ownername;
}
Now, for Unit test:
it('should update the customer number on selecting a value from drop down', () => {
component.customers = [{ ownerid: 1, ownerName: 'Person1' }, { ownerid: 2, ownerName: 'Person2' }];
spyOn(component, 'onCustomerChange').and.callThrough();
const e = fixture.debugElement.nativeElement.querySelectorAll('.selectCustomerData');
e[1].click();
expect(component.onCustomerChange).toHaveBeenCalledWith({ ownerid: 2, ownerName: 'Person2' });
expect(component.customerNumber).toBe(2);
expect(component.customerName).toBe('Person2');
});
You can refer to this blog to get very elaborate examples in Angular Unit Testing.
Upvotes: 2