Skip to main content

How to test usage of @angular/material (Angular Material) in Angular applications

Angular Material is a UI library with a lot of UI components. Below you can find information how to test a component which uses Angular Material.

The next example will be based on usage of mat-table. Let's assume, that a component uses mat-table like that:

<table mat-table [dataSource]="dataSource">  <!-- Position Column -->  <ng-container matColumnDef="position">    <th mat-header-cell *matHeaderCellDef>No.</th>    <td mat-cell *matCellDef="let element">      {{ element.position }}    </td>  </ng-container>
  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>  <tr    mat-row    *matRowDef="let row; columns: displayedColumns"  ></tr></table>

A test of such a template requires to:

  • mock mat-table
  • assert passed inputs
  • assert templates for Position column
  • assert the rest of templates
note

Information about testing ng-template and its TemplateRef is taken from the ngMocks.render.

Spec file#

With MockBuilder, our spec file needs a single line to provide mocks:

beforeEach(() => MockBuilder(TargetComponent, TargetModule));

Where TargetComponent is a component which uses mat-table, and TargetModule is its module.

Testing inputs of mat-table#

In this test we need to verify that mat-table data from out component's instance.

The tools from ng-mocks we need:

it('binds inputs', () => {  // Rendering TargetComponent and accessing its instance.  const targetComponent = MockRender(TargetComponent).point    .componentInstance;
  // Looking for a debug element of `MatTable`.  const tableEl = ngMocks.reveal(['mat-table']);
  // Asserting bound properties.  expect(ngMocks.input(tableEl, 'dataSource')).toBe(    targetComponent.dataSource,  );});

Testing matColumnDef and matCellDef templates#

To test the ng-template, we should find TemplateRef which belongs to matColumnDef and matCellDef attributes, render them, and assert the rendered html.

The tools from ng-mocks we need:

it('provides correct template for matColumnDef="position"', () => {  MockRender(TargetComponent);  // looking for the table and container  const tableEl = ngMocks.reveal(['mat-table']);  const containerEl = ngMocks.reveal(['matColumnDef', 'position']);
  // checking that there are no artifacts around  expect(ngMocks.formatHtml(containerEl)).toEqual('');
  // checking header  const headerEl = ngMocks.reveal(containerEl, [    'matHeaderCellDef',  ]);  ngMocks.render(tableEl.componentInstance, headerEl);  expect(ngMocks.formatHtml(headerEl)).toEqual(    '<th mat-header-cell="">No.</th>',  );
  // checking cell  const cellEl = ngMocks.reveal(containerEl, ['matCellDef']);  ngMocks.render(tableEl.componentInstance, cellEl, {    position: 'testPosition',  });  expect(ngMocks.formatHtml(cellEl)).toEqual(    '<td mat-cell=""> testPosition </td>',  );});

Testing mat-header-row template#

The approach to test mat-header-row is the same as above.

We need to find which directive belongs to mat-header-row, it is MatHeaderRowDef.

The tools from ng-mocks we need:

it('provides correct template for mat-header-row', () => {  const targetComponent = MockRender(TargetComponent).point    .componentInstance;  const tableEl = ngMocks.reveal(['mat-table']);
  // checking that there are no artifacts around  expect(ngMocks.formatHtml(tableEl)).toEqual('');
  const header = ngMocks.findInstance(tableEl, MatHeaderRowDef);  expect(header.columns).toBe(targetComponent.displayedColumns);  ngMocks.render(tableEl.componentInstance, header);  expect(ngMocks.formatHtml(tableEl)).toContain(    '<tr mat-header-row=""></tr>',  );});

Testing mat-row template#

The approach to test mat-row is the same as above.

We need to find which directive belongs to mat-row, it is MatRowDef.

it('provides correct template for mat-row', () => {  const targetComponent = MockRender(TargetComponent).point    .componentInstance;  const tableEl = ngMocks.reveal(['mat-table']);
  // checking that there are no artifacts around  expect(ngMocks.formatHtml(tableEl)).toEqual('');
  const row = ngMocks.findInstance(tableEl, MatRowDef);  expect(row.columns).toBe(targetComponent.displayedColumns);  ngMocks.render(tableEl.componentInstance, row);  expect(ngMocks.formatHtml(tableEl)).toContain(    '<tr mat-row=""></tr>',  );});