Using jest 26.6.3, I cannot make the second test here working fine. If I add logs, I can see the callback being called….
export class MyClass {
constructor() {}
public foo() {
console.log("foo");
}
}
And the test
import { MyClass } from "./MyClass";
jest.mock("./MyClass");
jest.useFakeTimers();
describe("MyClass", () => {
let myObject: MyClass = new MyClass();
beforeEach(() => {
jest.resetAllMocks();
});
it("works", () => {
const fooSpy = jest.spyOn(myObject, "foo");
myObject.foo();
expect(fooSpy).toHaveBeenCalledTimes(1);
});
it("does not work", async (done) => {
const fooSpy = jest.spyOn(myObject, "foo");
const callback = () => {
myObject.foo();
};
// Call the callback inside setInterval
const intervalId = setInterval(callback, 1000);
jest.advanceTimersByTime(1000);
// I also tried jest.runOnlyPendingTimers();
expect(fooSpy).toHaveBeenCalledTimes(1); // This will fail
done();
});
});
Is it a jest bug or am I doing something wrong?
Turned out the solution is this
beforeEach(() => {
jest.clearAllMocks();
jest.useRealTimers();
jest.useFakeTimers('modern'); // legacy won't work
});
So definitely sounds like a jest bug