1
votes

Let's say I have MyFile.js

export const test2 = () => {}
export const test = () => {
  test2();
}

Then I have MyFile.test.js for it:

import * as MyFile from "./MyFile";

it("when test() is called should call test2", () => {
  const spy = jest.spyOn(MyFile, "test2");
  MyFile.test();
  expect(spy).toHaveBeenCalled();
})

Why am I getting the error Expected mock function to have been called, but it was not called for this case?

1

1 Answers

2
votes

jest.spyOn wraps the property of an object in a spy.

MyFile represents the module exports from MyFile.js so jest.spyOn(MyFile, "test2"); wraps the module export for test2 in a spy...

...but when MyFile.test gets called it calls test2 directly so the spy never gets called.


One way to fix it is to move test2 into its own module:

MyFile.js

import { test2 } from './OtherModule';

export const test = () => {
  test2();
}

OtherModule.js

export const test2 = () => {}

MyFile.test.js

import * as MyFile from "./MyFile";
import * as OtherModule from "./OtherModule";

it("when test() is called should call test2", () => {
  const spy = jest.spyOn(OtherModule, "test2");
  MyFile.test();
  expect(spy).toHaveBeenCalled();  // Success!
})

The other way is to import the module bindings so you can call the module export for test2:

MyFile.js

import * as MyFile from './MyFile';  // <= import module bindings

export const test2 = () => {}
export const test = () => {
  MyFile.test2();  // <= call the module export for test2
}

MyFile.test.js

import * as MyFile from "./MyFile";

it("when test() is called should call test2", () => {
  const spy = jest.spyOn(MyFile, "test2");
  MyFile.test();
  expect(spy).toHaveBeenCalled();  // Success!
})