How to Write Unit Test Case with Mocking Service in Angular

Introduction

Writing unit tests with mocking services is a common practice in Angular to isolate the component being tested from external dependencies such as services. This allows you to test the component in isolation and focus on its behavior. Here's a step-by-step guide on how to write a unit test case with a mocked service in Angular using Jasmine and TestBed:

Let's assume you have a component called MyComponent that depends on a service called MyService. We'll create a mock for MyService and use it in the test.

Create the Component (my.component.ts)

// my.component.ts
import { Component, OnInit } from '@angular/core';
import { MyService } from './my.service';

@Component({
  selector: 'app-my',
  template: '<div>{{ data }}</div>',
})
export class MyComponent implements OnInit {
  data: string;

  constructor(private myService: MyService) {}

  ngOnInit(): void {
    this.data = this.myService.getData();
  }
}

Create the Service (my.service.ts)

// my.service.ts
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class MyService {
  getData(): string {
    return 'Hello from MyService!';
  }
}

Create the Unit Test (my.component.spec.ts)

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MyComponent } from './my.component';
import { MyService } from './my.service';

describe('MyComponent', () => {
  let component: MyComponent;
  let fixture: ComponentFixture<MyComponent>;
  let myServiceMock: jasmine.SpyObj<MyService>;

  beforeEach(() => {
    // Create a spy object for the service
    myServiceMock = jasmine.createSpyObj('MyService', ['getData']);

    TestBed.configureTestingModule({
      declarations: [MyComponent],
      providers: [{ provide: MyService, useValue: myServiceMock }],
    });

    fixture = TestBed.createComponent(MyComponent);
    component = fixture.componentInstance;
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('should set data from service', () => {
    // Configure the spy behavior
    myServiceMock.getData.and.returnValue('Mocked data');

    // Trigger ngOnInit
    component.ngOnInit();

    // Check if the data property has the expected value
    expect(component.data).toBe('Mocked data');
  });
});

In this example, we use the jasmine.createSpyObj function to create a spy object for the MyService class. We then provide this mock service in the testing module using the TestBed.configureTestingModule method.

The beforeEach function is used to set up the testing module, create a component fixture, and create an instance of the component.

In the second test, we configure the spy to return a specific value when the getData method is called, and then we call the ngOnInit method of the component to test its behavior.

This is a basic example, and you may need to adapt it to your specific use case. Keep in mind that Angular testing can involve more advanced scenarios, such as testing asynchronous code, dealing with forms, and interacting with the DOM.


Similar Articles