简体   繁体   中英

Angular material table filter testing

I'm trying to DOM test filtering of MatTable in Angular Material. I have a component named xxx-table , with an @Input() named filter .

This filter is copied into dataSource.filter using onNgChanges, like this:

export class XXXTableComponent implements OnInit, OnChanges {
    @Input()
    loadedDatas: Item[];

    @Input()
    filter: string = '';

  dataSource: MatTableDataSource<Suppressed>;

  @ViewChild(MatSort) sort: MatSort;

  ngOnInit(): void {
    this.dataSource = new MatTableDataSource(this.suppressedDevices);
    this.dataSource.sort = this.sort;
  }

    ngOnChanges(): void {
        if(this.dataSource) this.dataSource.filter = this.filter;
    }

我的过滤表 It is working fine in the UI, so I'm trying to DOM test it using fixture . It seems like it's not updating the DOM in real time. I tried like this:

  it('should filter the dataSource', () => {
    expect.hasAssertions();
    component.filter = 'New York';
    fixture.detectChanges();
    component.ngOnChanges();

    expect(component.dataSource.filter).toBe('New York');
    expect(component.dataSource.filteredData.length).toBe(1);

    expect(component.dataSource.filteredData[0].address).toBe(
      '43, Highway Road, 23413'
    );

    // Why isn't that passing?
    return fixture.whenStable().then(() => {
      const rows = fixture.nativeElement.querySelectorAll('tbody tr');

      expect(rows.length).toBe(1); // Fails here
      const cell = fixture.nativeElement
        .querySelector('tbody td:nth-child(3)')
            expect(cell.textContent)
        .toBe('43, Highway Road, 23413');
    });
  });

For fixture.whenStable to work you need to wrap your test in async:

  it('should filter the dataSource', async(() => {
    expect.hasAssertions();
    component.filter = 'New York';
    fixture.detectChanges();
    component.ngOnChanges();

    expect(component.dataSource.filter).toBe('New York');
    expect(component.dataSource.filteredData.length).toBe(1);

    expect(component.dataSource.filteredData[0].address).toBe(
      '43, Highway Road, 23413'
    );

    // Why isn't that passing?
    return fixture.whenStable().then(() => {
      const rows = fixture.nativeElement.querySelectorAll('tbody tr');

      expect(rows.length).toBe(1); // Fails here
      const cell = fixture.nativeElement
        .querySelector('tbody td:nth-child(3)')
            expect(cell.textContent)
        .toBe('43, Highway Road, 23413');
    });
  }));

I'm not exactly sure that's the problem, but I would try that.

So, for future reference, it wasn't working because fixture.detectChanges(); is called before component.ngOnChanges(); , so the changes were not detected.

Swapping them fixes the issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM