Angular 单元测试中未定义的 ag-grid API

Posted

技术标签:

【中文标题】Angular 单元测试中未定义的 ag-grid API【英文标题】:ag-grid API Undefined in Angular unit testing 【发布时间】:2021-04-03 13:06:51 【问题描述】:

我正在用 Angular 编写 Ag-grid 的单元测试用例。

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.gridApiundefined 而失败,所以它无法为网格this.gridApi.setRowData(this.rowData) 赋值。

【问题讨论】:

这个问题很有道理,我自己一直在努力让基于角度 ag-grid 的测试工作,因为答案看起来有助于解决问题,我建议不要关闭问题,因为它有帮助为使用 ag-grid 库的组件编写单元测试。我已经在 github 中询问了一个关于此的具体问题,但链接已被删除,因此您可以根据我在为 ag-grid 编写单元测试时的经验来解决这个问题。 【参考方案1】:

在编写涉及 ag-grid api 可用性的单元测试时,在这种情况下有两件事可以帮助您:

您可以尝试使用this.gridOptions.api (this.gridOptions.api.setRowData ...) 而不是等待gridReady 事件,因为大多数情况下,它会更快初始化(在 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 API的主要内容,如果未能解决你的问题,请参考以下文章

AG-Grid gridReady 未在使用 Angular 和 Jest 的测试中调用

Angular 4 单元测试中未调用 ngOnChanges detectChanges()

在 ag-grid 中使用自定义单元格渲染器时无法读取未定义的属性“导航”

Angular Ag-grid(值获取器不导出单元格的渲染值)

ag-Grid:我如何对 ICellRendererAngularComp 进行单元测试

如何根据Angular 6同一行中的其他单元格值在AG-Grid选择下拉列表中加载不同的选项?