Angular testing
Tags: mock, standalone, components, angular
Published: 2023-03-02 21:12:18

---
title: Angular testing
published: true
date: 2023-03-01 10:30:49 UTC
tags: mock,standalone,components,angular
canonical_url: https://medium.com/@redin.gaetan/angular-testing-dabc92a38b3f
---

How to mock natively component dependencies

Hey, I know there are many documentation about this but it seems to not be effective. Why? People does not read documentation… Every time I start a new mission, the developers don’t test their components or do it wrong. In the last case, they never mock their component dependencies and that’s a problem because it’s not a unit test anymore.

I think a little reminder is necessary.

### Context

I’m developing a CancelButtonComponent. It’s a material button with a specific text and specific mat-button properties.

I’m working on a standalone component.

I’m using jest and snapshot testing to be sure that the genereted HTML is as expected.

### How to

```
@Component({
  selector: 'app-cancel-button',
  standalone: true,
  template: `<button mat-button color="primary">Cancel</button>`,
  imports: [MatButtonModule]
})
export class CancelButton {}
```

It’s a really simple component and here we just have to control the generated HTML.

Here’s the spec file:

```
describe('CancelButtonComponent', () => {
  let component: CancelButtonComponent;
  let fixture: ComponentFixture<CancelButtonComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [CancelButtonComponent],
    }).compileComponents();

    fixture = TestBed.createComponent(CancelButtonComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(fixture.nativeElement).toMatchSnapshot();
  });
});
```

Here I don’t mock anything.

That’s the generated snapshot:

```
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`CancelButtonComponent should create 1`] = `
<div
  id="root0"
>
  <button
    class="mdc-button mat-mdc-button mat-primary mat-mdc-button-base"
    color="primary"
    mat-button=""
  >
    <span
      class="mat-mdc-button-persistent-ripple mdc-button__ripple"
    />
    <span
      class="mdc-button__label"
    >
      Cancel
    </span>
    <span
      class="mat-mdc-focus-indicator"
    />
    <span
      class="mat-ripple mat-mdc-button-ripple"
      matripple=""
    />
    <span
      class="mat-mdc-button-touch-target"
    />
  </button>
</div>
`;
```

I don’t think this snapshot is really relevant. I don’t care about MatButton specific css classes, I don’t care about all generated spans and that make a big snapshot just for one line of HTML to test. Snapshot is a part of your code it MUST be reviewed.

Now, let’s do better with a mock.

Here’s a simple mock for the MatButton:

```
@Component({
  selector: '[mat-button]',
  standalone: true,
  template: ` <ng-content></ng-content>`,
})
class MatButtonMock {}
```

I use the projection (<ng-content/>) to let the button’s text appear in the snapshot.

And that’s how to use it in the test:

```
beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [CancelButtonComponent],
    })
      .overrideComponent(CancelButtonComponent, {
        remove: {
          imports: [MatButtonModule],
        },
        add: {
          imports: [MatButtonMock],
        },
      })
      .compileComponents();

    ...
  });
```

We just tell to TestBed to remove the import of MatButtonModule for CancelButtonComponent and to replace it with our MatButtonMock.

Let’s see the snapshot now:

```
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`CancelButtonComponent should create 1`] = `
<div
  id="root0"
>
  <button
    color="primary"
    mat-button=""
  >
    Cancel
  </button>
</div>
`;
```

It’s so better. I see only the specifities of my CancelButtonComponent:

- usage of a mat-button
- set the color to primary
- set the text to “Cancel”

It’s more readable, it’s more reviewable and it’s more relevant.

Angular offers other methods to override a component in a test:

- overrideComponent
- overridePipe
- overrideDirective
- overrideModule
- overrideProviders

I put here the full spec file if you need it:

```
describe('CancelButtonComponent', () => {
  let component: CancelButtonComponent;
  let fixture: ComponentFixture<CancelButtonComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [CancelButtonComponent],
    })
      .overrideComponent(CancelButtonComponent, {
        remove: {
          imports: [MatButtonModule],
        },
        add: {
          imports: [MatButtonMock],
        },
      })
      .compileComponents();

    fixture = TestBed.createComponent(CancelButtonComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(fixture.nativeElement).toMatchSnapshot();
  });
});
```

### Conclusion

Never mind, you are using jest, Karma/jasmine or another testing tool. You always must mock your dependencies (components, services, pipes…) to avoid to be impacted by a third party in your test. And also because we are speaking about unit test.

If you need more examples or other testing use case, let me know in comment. I will try to help you.

Thanks for reading.

### Learn more

- [Install Jest for Angular](https://dev.to/gaetanrdn/jest-and-angular-install-fg3)
- [Angular for everyone: All about it](https://medium.com/@redin.gaetan/angular-for-every-one-table-of-contents-d24232940dd4)