1

I want to test if this.service.someMethod is called using jasmine spy.

Source file:

// src.ts
import { Service } from 'some-package';

export class Component {
   service = new Service();

   callMethod() {
      this.service.thatMethod();
   }
}

Spec file:

// src.spec.ts
import { Component } from './src';

describe('test', () => {
   it('calls thatMethod of service', () => {
      let comp = new Component();

      spyOn(comp.service, 'thatMethod').and.callThrough();

      comp.callMethod();

      expect(comp.service.thatMethod).toHaveBeenCalled();
   });
});

Output:

Failed test: Expected comp.service.thatMethod to have been called.

Anant_Kumar
  • 764
  • 1
  • 7
  • 23
  • 1
    Shouldn't `comp.thatMethod();` in your test be `comp.callMethod()`? –  May 06 '20 at 08:47

1 Answers1

2

I would suggest you to refactor your code and take advantage of IoC (inversion of control) pattern. That means that you have to get rid of Service dependency in your Component class and inject it manually, like this:

export class Component {
   constructor(service) {
       this.service = service;
   }

   callMethod() {
     this.service.thatMethod();
   }
}

// Elsewhere in your code
import { Service } from 'some-package';
const component = new Component(new Service());

This approach will allow you to test your components effectively with Service mock:

import { Component } from './src';

describe('test', () => {
    it('calls thatMethod of service', () => {
        const service = jasmine.createSpyObj('service', ['thatMethod']);
        let comp = new Component(service);

        comp.callMethod();
        expect(service.thatMethod).toHaveBeenCalled();
   });
});
oozywaters
  • 1,171
  • 1
  • 8
  • 17