Search code examples
angularjestjsangular-material

How to test the contents inside the material table cell?


there are two simple tests that look for elements and compare them to a number. First group of elements is located outside the . Second group of elements is located inside the <td mat-cell>.

Respectively, first unit-test is successfull, second unit-test is failed. I need all tests to be successful. Please help me to fix second unit-test.

jest tests:

it('test1', () => {
  const elements = fixture.debugElement.queryAll(By.css('[data-test="q1"]'));
  const elementsLength = elements.length;
  expect(elementsLength).toBe(3);
});

it('test2', () => {
  const elements = fixture.debugElement.queryAll(By.css('[data-test="q2"]'));
  const elementsLength = elements.length;
  expect(elementsLength).toBe(3);
});

angular template:

<div data-test="q1">q1</div>
<div data-test="q1">q1</div>
<div data-test="q1">q1</div>

<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
  <ng-container matColumnDef="position">
    <th mat-header-cell *matHeaderCellDef> No. </th>
    <td mat-cell *matCellDef="let element">

    <div data-test="q2">q2</div>
    <div data-test="q2">q2</div>
    <div data-test="q2">q2</div>

    {{element.position}}
   </td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>   

live demo is here.


Solution

  • The reason your test fails is because you have more than 3 such elements. It's because you render them in cycle.

    Here in your code you specify dataSource for the table with 10 elements in it:

      <table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
    

    For every element you render table row in cycle:

    <ng-container matColumnDef="position">
      <th mat-header-cell *matHeaderCellDef> No. </th>
      <td mat-cell *matCellDef="let element">
      <div data-test="q2">q2</div>
      <div data-test="q2">q2</div>
      <div data-test="q2">q2</div>
      {{element.position}}
     </td>
    </ng-container>
    

    So there will be 30 elements, not 3.

    Your best bet will be to test for an actual amount:

    expect(elementsLength).toBe(30);
    

    You could also specify unique test ids if you are interested in particular table row. In such case you would get your desired 3 elements for the row.