I am writing the unit test case for Ag-grid in angular.
test.component.ts:
public gridApi: GridApi;
public gridColumnApi;
constructor(private service: Service) {
this.initializeAgGrid(); // this method just initializing the grid
}
ngOnInit(): void {
this.setHraDashboardData();
}
onGridReady(params) {
this.gridApi = params.api;
this.gridColumnApi = params.columnApi;
this.gridApi.sizeColumnsToFit();
}
setHraDashboardData() {
this.service.getData(1).then((data) => {
this.uiData = data;
this.rowData = this.generateRowData(this.data); // this method writing some logic for UI
this.gridApi.setRowData(this.rowData);
});
}
test.component.spec.ts
beforeEach(() => {
fixture = TestBed.createComponent(HraFormComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('grid API is available after `detectChanges`', async() => {
await fixture.whenStable().then(()=>{
fixture.detectChanges();
const elm = fixture.debugElement.nativeElement;
const grid = elm.querySelector('#Grid');
const firstRowCells = grid.querySelectorAll('div[row-id="0"] div.ag-cell-value');
const values = Array.from(firstRowCells).map((cell: any) => cell.textContent.trim());
// assert
expect(component.rowData[0].title).toEqual(values[0]);
});
});
Now above test case is getting failed to due to component.gridApi
is undefined
, so it's not able to assign value for the grid this.gridApi.setRowData(this.rowData)
.
When writing unit tests that involves the availability of the ag-grid api, two things can help you in this case:
Instead of waiting for the gridReady
event, you can try to use the this.gridOptions.api
(this.gridOptions.api.setRowData ...) because most of the time, it is initialized sooner (before onGridReady firing)
You can do that in combination of using a settimeout function as well, I used that multiple times when I got a similar issue as yours in the past:
instead of:
this.gridApi.setRowData(this.rowData);
Try:
setTimeout(() => { this.gridApi.setRowData(this.rowData);}, 100);
You can increase the time for the settimeout to 200, 300, 500 or more, for me, most of the time just using the settimeout
with a very small number (10 milliseconds) worked.
The settimeout is not an ideal solution but that works in many cases. The first options should be more clean, and you can even add a timeout as well to get it to work.
Use a fakeAsync zone instead of the async
one will help as well.