Show List

Mock Dependent Services

For unit testing we do not always have to call the real dependent services. There are several ways we can use mock services in the Jasmine tests. Below is a component that uses MessageService to get a message to display on the user screen. MessageService may internally be calling an API to return the message based on the time of the year. 

greet.component.ts
import { Component, OnInit } from '@angular/core';
import { MessageService } from '../message.service';

@Component({
  selector: 'app-greet',
  templateUrl: './greet.component.html',
  styleUrls: ['./greet.component.css']
})
export class GreetComponent implements OnInit {

  response: any;
  constructor(private svc: MessageService) { }

  ngOnInit(): void {
    this.response = this.svc.getMessage();
  }

}

greet.component.html
{{response.message}}
message.service.ts
It calls the API to get the message based on the time of the year. Like "Happy New Year", "Happy Thanksgiving", "Merry Christmas". Sample response: {message: "Happy New Year"}
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class MessageService {

  API_URL: string;
  constructor() {
    this.API_URL = "some_url";
  }

  getMessage() {
    //Call API to get the greeting message based on the time of the year. Like "Happy New Year", "Happy Thanksgiving", "Merry Christmas". Sample response: {message: "Happy New Year"}
    return this.http.get(this.API_URL);
  }
}

Here is the test class if we were to test the component with real service

greet.component.spec.ts
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MessageService } from '../message.service';

import { GreetComponent } from './greet.component';

describe('GreetComponent Test Suite', () => {
  let component: GreetComponent;
  let service: MessageService;

  beforeEach(async () => {

    service = new MessageService();
    component = new GreetComponent(service);
  });

  it('Data field should be Happy New Year when the service returns Happy New Year', () => {
    component.ngOnInit();
    expect(component.response.message).toBe("Happy New Year");
  });
});

There could be cases such as the real service is not available in test environment or we are not sure what message the real service would return on a specific day. So we need to test the component with a mock service.

Mocking Service by Overriding

Here is an example of creating a mock service by extending the real service. The service function is overridden to supply the test data to the component.

greet.component.spec.ts
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MessageService } from '../message.service';

import { GreetComponent } from './greet.component';

class MockMessageService extends MessageService {
  override getMessage() {
    return {message: "Happy New Year"};
  }
}

describe('GreetComponent Test Suite', () => {
  let component: GreetComponent;
  let service: MockMessageService;

  beforeEach(async () => {
    service = new MockMessageService();
    component = new GreetComponent(service);
  });

  it('Data field should be Happy New Year when the service returns Happy New Year', () => {
    component.ngOnInit();
    expect(component.response.message).toBe("Happy New Year");
  });
});


Mocking Service Using Spy

Spy is a feature of Jasmine that allows to control what is returned by a function.
import { MessageService } from '../message.service';

import { GreetComponent } from './greet.component';

describe('GreetComponent Test Suite', () => {
  let component: GreetComponent;
  let service: MessageService;
  let spy: any;

  beforeEach(async () => {
    service = new MessageService();
    component = new GreetComponent(service);
  });

  it('Data field should be Happy New Year when the service returns Happy New Year', () => {
    let mockResp = { message: "Happy New Year" };
    spy = spyOn(service, 'getMessage').and.returnValue(mockResp);
    component.ngOnInit();
    expect(component.response.message).toBe("Happy New Year");
  });
});


Source code
https://github.com/it-code-lab/angular-application

    Leave a Comment


  • captcha text