how to work with jest toHaveBeenCalled with different instance

Viewed 1198

So I am writing a test case for one of my function where I am making a call to another function of a library and I am trying to mock that function(saveCall), here is the sample code:

import { Call } from './somefolder/call';
class Demo {
  var testIt = (params: any) => {
    ---- // Some other code
    let call = new Call(params);
    call.saveCall();
    ---- // Some other code
  }
 return {testIt: testIt};
}

And here is how I am writing unit test case for the same:

import { Call } from './somefolder/call';
var demo = new Demo();
test("Test it", () => {
    let call = new Call({} as any);
    let spyIt = jest.spyOn(call, 'saveCall').mockImplementation(()=>{console.log('here')});
    demo.testIt();
    expect(spyIt).toHaveBeenCalled(); // Throws error expect(jest.fn()).toHaveBeenCalled()
    
});

I am getting expect(jest.fn()).toHaveBeenCalled() error in expect, Now I feel I am getting error because the instance of call object in test file is different from what I have in Demo class and that is the reason spyOn doesn't know that whether the function has been called or not. I did try with mocking the entire Call.ts file but getting the same error. Now my question is how can I create a mock and sucessfully test whether saveCall() has been called. Please note that I cannot change the implementation of testIt function.

1 Answers

Using jest.mock helper to mock Call class and assert on instance of the mocked class.

import { Call } from './somefolder/call';
import { Demo } from './Demo';

jest.mock('./somefolder/call'); // mock all named export items

describe("Demo", () => {
  let demo: Demo;
  let CallMocked: jest.Mock<Call>; // define type for mocked class

  beforeEach(() => {
    CallMocked = Call as any; // Actually, now Call is a mocked class
    demo = new Demo();
  });

  test("Test it", () => {
    demo.testIt();
    expect(CallMocked.mock.instances[0].saveCall).toHaveBeenCalled(); // assert for mock instance
  });
})
Related