Roei Rom
Roei Rom

Reputation: 165

How can I tell if another object method has been called

I have my object of functions and I'd like to test if 1 method has called the other one but spy seems to fail because the test says it's due to that the function haven't been called at all. I'm adding the code.
index.js

const funcObject = () => {
    const firstFunc = () => {
        console.log('first func!')
    };
    const secondFunc = () => {
        firstFunc();
        console.log('second func!');
    }
    return {
        firstFunc,
        secondFunc
    };
};

module.exports = funcObject;

index.test.js

const funcObject = require('./index');

describe('second func tests', () => {
    it('should call first func', () => {
        const funcObjectOutput = funcObject();
        const firstFuncSpy = jest.spyOn(funcObjectOutput, 'firstFunc');
        funcObjectOutput.secondFunc();

        expect(firstFuncSpy).toHaveBeenCalled();
    })
})

package.json

{
  "name": "jest-mock",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
    "test": "jest"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/jest": "^26.0.20",
    "jest": "^26.6.3"
  }
}

Upvotes: 0

Views: 680

Answers (2)

小聪聪到此一游
小聪聪到此一游

Reputation: 1294

jest.spyOn(funcObjectOutput, 'firstFunc') replaces funcObjectOutput['firstFunc'] with a mock function. So firstFuncSpy is the mock one rather than original. And expect(firstFuncSpy).toHaveBeenCalled() checks whether the mock function has been called. But secondFunc calls the original firstFunc.

See code of jest.spyOn. https://github.com/facebook/jest/blob/dd1309652334ab14544cf3ecb177faae68059832/packages/jest-mock/src/index.ts#L951

Upvotes: 1

Lin Du
Lin Du

Reputation: 102317

For now, the firstFunc() called inside the secondFunc() will be original function, NOT spied version.

In order to spy or mock the firstFunc() function, you need to retrieve the reference of it. In this way, when the secondFunc() function is called, the spied firstFunc() function will be called. For more info, see this How to mock specific module function?

E.g.

index.js:

const funcObject = () => {
  const obj = {};
  const firstFunc = () => {
    console.log('first func!');
  };
  const secondFunc = () => {
    obj.firstFunc();
    console.log('second func!');
  };

  obj.firstFunc = firstFunc;
  obj.secondFunc = secondFunc;
  return obj;
};

module.exports = funcObject;

index.test.js:

const funcObject = require('./index');

describe('second func tests', () => {
  it('should call first func', () => {
    const funcObjectOutput = funcObject();
    const firstFuncSpy = jest.spyOn(funcObjectOutput, 'firstFunc');
    funcObjectOutput.secondFunc();

    expect(firstFuncSpy).toHaveBeenCalled();
  });
});

test result:

 PASS  examples/66657164/index.test.js
  second func tests
    ✓ should call first func (19 ms)

  console.log
    first func!

      at Object.firstFunc (examples/66657164/index.js:4:13)

  console.log
    second func!

      at Object.secondFunc (examples/66657164/index.js:8:13)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        5.69 s

Upvotes: 0

Related Questions