skip to Main Content

I am using Jest for my testing environment and I am trying to see if a method in the tested module calls another method at least once.

Here is the nested.js module:

export function getUserData() {
  console.log("CALLING API");
  const user = {
    name: "user",
  };
  setUserData(user);
}

export function setUserData(user) {
  console.log("Setting user data");
}

And here is the nested.test.js:

import * as nested from "../nested";
let storeUserDataSpy = jest.spyOn(nested, "setUserData");

describe("Get user data calls child method", () => {
  it("should call the child method", async () => {
    nested.getUserData();
    expect(storeUserDataSpy).toHaveBeenCalledTimes(1);
  });
});

The error that I am getting is that the method has not been called at all:

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

I tried various ways of resolving the issue including jest.mock and including the actual methods from the nested.js module.

What I don’t want to do is to spyOn console logs as these won’t be included in the production code.

I uploaded the code with all the Jest and Babel config to a GitHub repo.

Here are the steps to try it locally:

git clone [email protected]:verebes1/tests-jest.git
cd tests-jest
npm install
npm run test

2

Answers


  1. Chosen as BEST ANSWER

    I found a solution based on another answer by using the Rewire package, and by including it as a babel plugin. Here is the code:

    nested.js

    export function getUserData() {
      console.log("CALLING API");
      const user = {
        name: "user",
      };
      setUserData(user);
    }
    
    export function setUserData(user) {
      console.log("Setting user data");
    }
    

    And the nested.test.js

    import __RewireAPI__, * as nested from "../nested";
    let storeUserDataSpy = jest.spyOn(nested, "setUserData");
    
    describe("Get user data calls child method", () => {
      it("should call the child method", async () => {
        __RewireAPI__.__Rewire__('setUserData', storeUserDataSpy);
        nested.getUserData();
        expect(storeUserDataSpy).toHaveBeenCalledTimes(1);
      });
    });
    

    finally .babelrc

    {
      "presets": [
        "@babel/preset-env"
      ],
      "plugins": [
        "rewire"
      ]
    }
    

    The answer-from-stack-overflow-using-rewire branch on the repo is updated with the above


  2. Easy way to achieve that is to extract function you want to spy on to separate file and spy on that.

    Test file nested.test.js

    import {getUserData} from "../nested";
    import * as utils from './utils'
    
    
    let storeUserDataSpy = jest.spyOn(utils, "setUserData");
    
    describe("Get user data calls child method", () => {
      it("should call the child method", async () => {
        getUserData();
        expect(storeUserDataSpy).toHaveBeenCalledTimes(1);
      });
    });
    

    Code file nested.js

    import {setUserData} from "./test/utils";
    
    export function getUserData() {
      console.log("CALLING API");
      const user = {
        name: "user",
      };
      setUserData(user);
    }
    

    Utils utils.js

    export function setUserData(user) {
        console.log("Setting user data");
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search