Home > Software design >  How can I spy the second function in this case object.functionOne().functionTwo() with Jest
How can I spy the second function in this case object.functionOne().functionTwo() with Jest

Time:10-20

I want to spy the functionTwo, but functionTwoSpy doesn't detect when functionTwo is called and test fails.

This is a simplified example of what I want to do:

describe('', () => {
  const object = {
    functionOne: () => ({
      functionTwo: () => {}
    })
  };

  const execute = object => object.functionOne().functionTwo();

  it('should be call functionOne', () => {
    const functionOneSpy = jest.spyOn(object, 'functionOne');

    execute(object);

    expect(functionOneSpy).toHaveBeenCalled();
  });

  it('should be call functionTwo', () => {
    const functionTwoSpy = jest.spyOn(object.functionOne(), 'functionTwo');

    execute(object);

    expect(functionTwoSpy).toHaveBeenCalled();
  });
});

and the error is this:

    ✓ should be call functionOne (2 ms)
    ✕ should be call functionTwo (3 ms)

●  › should be call functionTwo

expect(jest.fn()).toHaveBeenCalled()

Expected number of calls: >= 1
Received number of calls:    0

  21 |     execute(object);
  22 |
> 23 |     expect(functionTwoSpy).toHaveBeenCalled();
     |                            ^
  24 |   });
  25 | });

  at Object.<anonymous> (core/decorators/auth/test.spec.ts:23:28)
      at runMicrotasks (<anonymous>)

Some recommendation? Thanks

CodePudding user response:

Every time you get functionTwo using the functionOne method, you get back a new instance of functionTwo. This includes with jest.spyOn so there's no way at the moment to get the same instance each time. What you can do instead is assign a jest mock function to functionTwo so that you can assert that mock function was called later on.

describe('', () => {
    const funcTwoMock = jest.fn()
    const object = {
        functionOne: () => ({
            functionTwo: funcTwoMock
        })
    };

    const execute = object => object.functionOne().functionTwo();

    it('should be call functionOne', () => {
        const functionOneSpy = jest.spyOn(object, 'functionOne');

        execute(object);

        expect(functionOneSpy).toHaveBeenCalled();
    });

    it('should be call functionTwo', () => {
        execute(object);

        expect(funcTwoMock).toHaveBeenCalled();
    });
}

Now, even though functionTwo is a new instance each time, it always points back to the same funcTwoMock which jest is properly tracking

  • Related