0

I wonder why the last assert (expect(msgSpy).toBeCalled()) in this example fails. What do I need to change to make it pass?

  it('spyOn test', () => {
    const newClient = () => {
      const getMsg = () => {
        return 'dear spyOn';
      };
      const getHello = () => {
        return `Hello, ${getMsg()}`;
      };
      return {
        getMsg,
        getHello,
      };
    };

    const c = newClient();
    const helloSpy = jest.spyOn(c, 'getHello');
    const msgSpy = jest.spyOn(c, 'getMsg');

    expect(c.getHello()).toEqual('Hello, dear spyOn');

    expect(helloSpy).toBeCalled(); // asserts to true
    expect(msgSpy).toBeCalled();   // <-- asserts to false!
  });
Faber
  • 1,504
  • 2
  • 13
  • 21
  • 1
    getHello doesn't access getMsg via the object c. Same problem as https://stackoverflow.com/questions/45111198/how-to-mock-functions-in-the-same-module-using-jest/70066090#70066090. – jonrsharpe Apr 25 '23 at 11:40

1 Answers1

0

Spying works if we access getMsg in getHello through the object that we spy on. Hence, a possible solution could be:

it('spyOn test', () => {
  const newClient = () => {
    const getMsg = () => {
      return 'dear spyOn';
    };
    const r = {
      getMsg,
      getHello: () => {
        return `Hello, ${r.getMsg()}`;
      },
    };

    return r;
  };

  const c = newClient();
  const helloSpy = jest.spyOn(c, 'getHello');
  const msgSpy = jest.spyOn(c, 'getMsg');

  expect(c.getHello()).toEqual('Hello, dear spyOn');

  expect(helloSpy).toBeCalled(); // asserts to true
  expect(msgSpy).toBeCalled(); // <-- asserts to true now!
});

Faber
  • 1,504
  • 2
  • 13
  • 21