API ag-grid не определено в модульном тестировании Angular

Я пишу модульный тестовый пример для 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).

Вопрос имеет смысл, я сам изо всех сил пытался заставить работать тесты на основе angular ag-grid, поскольку ответ, похоже, помог решить проблему, я рекомендую не закрывать вопрос, потому что это помогает написать модульный тест для компонентов, которые используют библиотека ag-grid. Я задал конкретный вопрос об этом в github, но ссылка была удалена, так что здесь у вас есть способ обойти это, исходя из опыта, который я получил при написании модульных тестов для ag-grid.

HDJEMAI 27.12.2020 22:57
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
2
1
3 577
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

При написании модульных тестов, предполагающих доступность 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.

Другие вопросы по теме