jest.restoreAllMocks和mockFn.mockReset不能恢复我未被模拟的函数

fae0ux8s  于 9个月前  发布在  Jest
关注(0)|答案(1)|浏览(92)

我正在学习jest试图了解mockClear()mockReset()mockRestore()是如何工作的。我在我的calc.test.js文件中写了下面的代码。

import {add} from "./calc";

jest.mock("./calc", () => {
  return {
    add: jest.fn(),
  };
});

describe("testing calculator functions", () => {
  test("mocking add function and testing", () => {
    add.mockImplementation((a, b) => a * b);
    expect(add(1, 2)).toBe(2);
  });

  test("testing add without mocking", () => {
    add.mockRestore();
    expect(add(1, 2)).toBe(3);
  });
});

字符串
第一个测试如预期的那样通过了。但是我的第二个测试失败了。我得到的错误是:

Expected: 3
Received: undefined


在第二个测试用例中,我也用jest.restoreAllMocks();替换了add.mockRestore();,但我得到了相同的错误。
我还尝试在第一个测试用例中移动add.mockRestore();,结果还是同样的错误。
我的理解是,mockFn.mockRestore()恢复了原始(非模拟)实现。因此,在我的第二个测试用例中,add(1,2)应该是3。如果我使用mockReset()代替mockRestore()undefined应该是输出,但为什么我使用mockRestore()时得到undefined
下面的代码运行正常。两个测试用例都通过了,但是在这个场景中没有使用mockRestore()的要求。在mock时如何使用mockRestore()

describe("testing calculator functions", () => {
  test("mocking add function and testing", () => {
    const mockAdd = jest.fn().mockImplementation((a, b) => a * b);
    expect(mockAdd(1, 2)).toBe(2);
  });

  test("testing add without mocking", () => {
    expect(calc.add(1, 2)).toBe(3);
  });
});

r6vfmomb

r6vfmomb1#

这是因为add函数是作为模拟版本导入的,因为jest.mock()是在顶层调用的,* 原始实现永远不会导入。
所以作为修复,你需要修改你的代码来导入add函数的原始实现,并使用 * jest.spyOn() * 来模拟它。使用它,你可以保留对add的原始实现的引用,并可以在以后恢复它。类似于(代码没有测试,但你明白了):

import * as calc from "./calc";

const addSpy = jest.spyOn(calc, 'add');

describe("testing calculator functions", () => {
  test("mocking add function and testing", () => {
    addSpy.mockImplementation((a, b) => a * b);
    expect(calc.add(1, 2)).toBe(2);
    addSpy.mockClear(); // <-- Clear the mock to ensure it doesn't affect other tests
  });

  test("testing add without mocking", () => {
    addSpy.mockRestore(); // <--- Restore to the original implementation
    expect(calc.add(1, 2)).toBe(3);
  });
});

字符串

编辑:

根据你的评论,既然你只想使用jest.mock,那么我能想到的一种方法就是使用 * jest.requireOriginal() *。

import { add as mockedAdd } from "./calc";
const { add: actualAdd } = jest.requireActual("./calc");
jest.mock("./calc", () => {
  return {
    add: jest.fn(),
  };
});

describe("testing calculator functions", () => {
  test("mocking add function and testing", () => {
    mockedAdd.mockImplementation((a, b) => a * b);
    expect(mockedAdd(1, 2)).toBe(2);
    mockedAdd.mockClear();
  });

  test("testing add without mocking", () => {
    mockedAdd.mockImplementation(actualAdd); <-- Notice this
    expect(mockedAdd(1, 2)).toBe(3);
  });
});


为了回答您在编辑中添加的最新问题,No!mockFn.mockRestore只适用于用jest.spyOn创建的模拟函数。

  • 参考资料 *

相关问题