I'm testing the functionality of two button clicks and whether or not a modal opens as a result.
I've done several variations of testing these clicks in Jasmine, and I'm not sure how to pinpoint the cause of this error, or how to mitigate it:
TypeError: Cannot read properties of null (reading 'click')
component.spec.ts
describe('MyComponent', () => {
let component: MyComponent;
let fixture: ComponentFixture<MyComponent>;
beforeEach(() => {
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
fit('can promote', () => {
// ARRANGE
// spyOn(component, 'doPromoteMethod'); // no changes if uncommented
const dialog = TestBed.inject(MatDialog) as jasmine.SpyObj<MatDialog>;
const dialogRef = TestBed.inject(MatDialogRef) as jasmine.SpyObj<MatDialogRef<any>>;
dialog.open.and.returnValue(dialogRef);
dialogRef.afterClosed.and.returnValue(of());
queryParams$.next({});
// ACT
// 1st click evt: Ellipsis menu click (opens dropdown) //
const ellipsisBtn: HTMLButtonElement = fixture.nativeElement.parentNode.querySelector('[data-atm="actions"]');
ellipsisBtn.click();
fixture.detectChanges();
// 2nd click evt: Btn click //
const promoteBtn: HTMLButtonElement = fixture.nativeElement.parentNode.querySelector('[data-atm="promote"]');
promoteBtn.click();
fixture.detectChanges();
fixture.whenStable();
// ASSERT
expect(dialog.open).toHaveBeenCalled;
});
});
component.html
<ng-container matColumnDef="action">
<th mat-header-cell *matHeaderCellDef=""></th>
<td mat-cell *matCellDef="let promotion">
<button mat-icon-button
class="ellipsis-btn"
data-atm="actions"
[matMenuTriggerFor]="menu"
[matMenuTriggerData]="{ 'promotion': promotion }"
role="menubar">
<img src="/assets/icon/ellipsis-menu.svg" />
</button>
</td>
</ng-container>
<mat-menu class="promotion-menu" #menu="matMenu">
<ng-template matMenuContent let-promotion="promotion">
<div class="promotion-menu">
<button *ngIf="shouldAllowPromotion(promotion)" mat-menu-item data-atm="promote" (click)="doPromoteMethod(promotion)">Do promotion</button>
</div>
</ng-template>
</mat-menu>