Я пишу модульный тестовый пример для Ag-grid в 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]);
});
});
Теперь приведенный выше тестовый пример не проходит из-за того, что component.gridApi
является undefined
, поэтому он не может присвоить значение сетке this.gridApi.setRowData(this.rowData)
.
При написании модульных тестов, предполагающих доступность API ag-grid, в этом случае вам могут помочь две вещи:
Вместо того, чтобы ждать события gridReady
, вы можете попробовать использовать this.gridOptions.api
(this.gridOptions.api.setRowData...), потому что в большинстве случаев он инициализируется раньше (до срабатывания onGridReady)
Вы также можете сделать это в сочетании с функцией settimeout, я использовал ее несколько раз, когда в прошлом сталкивался с проблемой, похожей на вашу:
вместо:
this.gridApi.setRowData(this.rowData);
Пытаться:
setTimeout(() => { this.gridApi.setRowData(this.rowData);}, 100);
Вы можете увеличить время для settimeout до 200, 300, 500 или более, для меня большую часть времени работало просто использование settimeout
с очень небольшим числом (10 миллисекунд).
settimeout не идеальное решение, но оно работает во многих случаях. Первые варианты должны быть более чистыми, и вы даже можете добавить тайм-аут, чтобы заставить его работать.
Также поможет использование зоны fakeAsync вместо зоны async
.
Вопрос имеет смысл, я сам изо всех сил пытался заставить работать тесты на основе angular ag-grid, поскольку ответ, похоже, помог решить проблему, я рекомендую не закрывать вопрос, потому что это помогает написать модульный тест для компонентов, которые используют библиотека ag-grid. Я задал конкретный вопрос об этом в github, но ссылка была удалена, так что здесь у вас есть способ обойти это, исходя из опыта, который я получил при написании модульных тестов для ag-grid.