Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

293
Views
How to mock service function in Angular component for unit test

I am writing unit test for angular app, I am testing if the service function returns a value.

component.spec.ts

import {TopToolBarService} from '../../top-toolbar/top-toolbar.service';

beforeEach(async(() => {
   TestBed.configureTestingModule ({
   declarations: [ UsersListComponent],
   providers: [TopToolBarService],//tried mocking service here,still test failed
   schemas:[CUSTOM_ELEMENTS_SCHEMA]
 })
  .compileComponents();
}));



beforeEach(() => {
    fixture = TestBed.createComponent(UserListComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });



  it('should return data from service function', async(() => {
    let mockTopToolBarService: jasmine.SpyObj<TopToolBarService>;
    mockTopToolBarService = jasmine.createSpyObj('TopToolBarService', ['getCustomer']);
    mockTopToolBarService.getCustomer.and.returnValue("king");
    fixture.detectChanges();
    expect(component.bDefine).toBe(true); //fails
  }))

component.ts

bDefine = false;
ngOnInit() {
 let customer = this.topToolBarService.getCustomer();
 if (customer == null) {
   bDefine = false;
 } else {
    bDefine = true;
   }
}

I believe I have mocked the service function in my test, so I expect it must have reached else part where variable is set to 'true'.

TopToolBarService.ts

import { EventEmitter, Injectable, Output } from "@angular/core";

@Injectable()
export class TopToolBarService {
customer = null;

  getCustomer() {
    return this.customer;
  }
}
over 4 years ago · Santiago Trujillo
5 answers
Answer question

0

The answer from @Pedro Bezanilla is good enough. Just here's another way with less code, given the service is a singleton, which I think is most of the case.

The difference is that there's no provider configuration given to configureTestingModule. The spy is set up by spyOn against the service object taken from TestBed instead.

Calling TestBed.inject instead of TestBed.get is because it is deprecated since v9.0.0.

For singleton services, here's a doc in Angular website, and for completion, keep it in mind this GitHub issue.

describe('Component TEST', () => {
  ...
  let mockToolBarService: TopToolBarService;
  ...
  beforeEach(waitForAsync(() => {
    TestBed.configureTestingModule({
      declarations: [ UsersListComponent ],
      schemas:[ CUSTOM_ELEMENTS_SCHEMA ]
    });
    mockTopToolBarService = TestBed.inject(TopToolBarService);
    spyOn(mockTopToolBarService, 'getCustomer').and.returnValue(of([]));
  }));
  ...
over 4 years ago · Santiago Trujillo Report

0

You might consider usage of ng-mocks to avoid all that boilerplate to configure TestBed.

beforeEach(() => MockBuilder(UsersListComponent)
  .mock(TopToolBarService, {
    // adding custom behavior to the service
    getCustomer: jasmine.createSpy().and.returnValue('king'),
  })
);

it('should return data from service function', () => {
  const fixture = MockRender(UsersListComponent);
  // now right after the render the property should be true
  expect(fixtur.point.componentInstance.bDefine).toBe(true);
}));
over 4 years ago · Santiago Trujillo Report

0

Change your provider value

beforeEach(() => {
   TestBed.configureTestingModule({
      declarations: [ UsersListComponent],
      providers: [{
         provide: TopToolBarService,
         useValue: jasmine.createSpyObj('TopToolBarService', ['getCustomer'])
      }],
      schemas:[CUSTOM_ELEMENTS_SCHEMA]
     });
     mockTopToolBarService = TestBed.get(TopToolBarService);

     mockTopToolBarService.getCustomer.and.returnValue(of([])); // mock output of function
   })

over 4 years ago · Santiago Trujillo Report

0

You have to configure the testing module before you run your code. It doesn't know about your spy object unless you pass it to the TestBed.configureTestingModule as an import.

https://angular.io/guide/testing#component-with-a-dependency

over 4 years ago · Santiago Trujillo Report

0

Try updating providers inside beforeEach(async(() => ...) and moving your mockedService variable on the top of it:

describe('Component TEST', () => {
   ...
   let mockToolBarService;
   ...
      beforeEach(async(() => {
      ...
      mockToolBarService = jasmine.createSpyObj(['getCustomer']);
      mockToolBarService.getCustomer.and.returnValue('king');
      TestBed.configureTestingModule ({
           ...
           providers: [ { provide: TopToolBarService, useValue: mockToolBarService } ]
           ...

Hope it helps!

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!