如何在 Angular Ag Grid 中测试 AgRendererComponent 组件

Posted

技术标签:

【中文标题】如何在 Angular Ag Grid 中测试 AgRendererComponent 组件【英文标题】:How to test AgRendererComponent component in Angular Ag Grid 【发布时间】:2020-11-23 15:36:07 【问题描述】:

我有一个自定义单元格渲染器组件,它将文本转换为链接。它一切正常。我正在尝试对渲染器组件进行单元测试。单元测试中面临的问题是网格显示带有链接,但当我通过本机元素查询时它不可用,我得到的值是空的,其他网格值已经存在,我可以看到它。我认为这与测试或 AG Grid 渲染的生命周期有关。如何告诉测试框架等到组件渲染完成?

链接渲染器组件

@Component(
    template: '<a [routerLink]="[params.inRouterLink,params.value]"  (click)="navigate(params.inRouterLink)">params.value</a>'
)
export class RouterLinkRendererComponent implements AgRendererComponent 
    params: any;

    constructor(
        private ngZone: NgZone,
        private router: Router)  

    agInit(params: any): void 
        this.params = params;
    

    refresh(params: any): boolean 
        return false;
    

测试组件:

@Component(
  template: `
    <ag-grid-angular
      style="width: 500px; height: 500px;"
      class="custom-theme"
      [rowData]="rowData"
      [columnDefs]="columnDefs"
      (gridReady)="onGridReady($event)"
    >
    </ag-grid-angular>
  `
)
export class TestCustomComponent 
  columnDefs = [
    
      headerName: 'Make',
      field: 'make',
      cellRendererFramework: RouterLinkRendererComponent,
      cellRendererParams: 
        inRouterLink: '/#'
      
    ,
     headerName: 'Model', field: 'model' ,
     headerName: 'Price', field: 'price' 
  ];

  rowData = [
     make: 'Toyota', model: 'Celica', price: 35000 ,
     make: 'Ford', model: 'Mondeo', price: 32000 ,
     make: 'Porsche', model: 'Boxter', price: 72000 
  ];

单元测试

fdescribe('AgnavigatorComponent', () => 
  let component: TestCustomComponent;
  let fixture: ComponentFixture<TestCustomComponent>;

  beforeEach(async(() => 
    TestBed.configureTestingModule(
      declarations: [RouterLinkRendererComponent, TestCustomComponent],
      imports: [
        RouterTestingModule,
        AgGridModule.withComponents([RouterLinkRendererComponent])
      ]
    ).compileComponents();
  ));

  beforeEach(() => 
    fixture = TestBed.createComponent(TestCustomComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  );

  it('should create', () => 
    const appElement = fixture.nativeElement;
    // here the values are empty only for the first column which uses custom renderer.
    const cellElements = appElement.querySelectorAll('.ag-cell-value');
  );
);

一旦测试执行完成,我可以看到带有正确值的列,其中包含 href。

【问题讨论】:

【参考方案1】:

问题是在执行时组件尚未加载。所以必须引入 SO.post 中提到的等待功能,我必须等到这个人进来。

export const waitUntil = async (
  untilTruthy: () => boolean
): Promise<boolean> => 
  while (!untilTruthy()) 
    await interval(25)
      .pipe(take(1))
      .toPromise();
  
  return Promise.resolve(true);
;

测试如下

  it('should render the component', async done => 
    let appElement: any;
    let cellElement: any;
    fixture.detectChanges();
    await fixture.whenStable();
    await waitUntil(() => 
      appElement = fixture.nativeElement;
      cellElement = appElement.querySelectorAll('.ag-cell-value');
      if (cellElement[0].textContent !== '') 
        return true;
      
      return false;
    );
    expect(cellElement[0].children[0].children[0].href.split('/')[3]).toEqual(
      'Toyota'
    );
    done();
  );

【讨论】:

以上是关于如何在 Angular Ag Grid 中测试 AgRendererComponent 组件的主要内容,如果未能解决你的问题,请参考以下文章

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

单元测试 - onGridReady - Angular 中的 Ag-grid 事件

如何在 ag-grid 中为 Angular 2 进行分页

如何在 Angular 6 中将工具提示文本包装在 ag-grid [关闭]

如何在 Angular 项目中自动刷新 ag-grid 中的单元格

如何在 ag-grid Angular 中添加过滤器?