首页 > 解决方案 > 来自另一个模块的 Jest 模拟函数:结果值未定义

问题描述

我正在练习用 Jest 进行测试,尤其是模拟函数。

我正在测试一个返回 double 参数的函数。我正在通过模拟它并映射几个参数来测试这个函数。

这是我正在测试的函数,它位于文件(“./mock-func.js”)中:

function doubling(n) {
  return n * 2;
}

exports.module = doubling;

这是测试(在另一个文件中):

const mockFunc = require("./mock-func.js");

mockFunc.doubling = jest.fn();

test("map calls functions correctly", () => {
  const a = [10, 20, 30];

  a.map(mockFunc.doubling);

  expect(mockFunc.doubling.mock.calls.length).toBe(3);
  expect(mockFunc.doubling.mock.calls[0]).toEqual([10, 0, a]);
  expect(mockFunc.doubling.mock.calls[1]).toEqual([20, 1, a]);
  expect(mockFunc.doubling.mock.calls[2]).toEqual([30, 2, a]);
  expect(mockFunc.doubling.mock.results[0].value).toBe(20);
  expect(mockFunc.doubling.mock.results[1].value).toBe(40);
  expect(mockFunc.doubling.mock.results[2].value).toBe(60);
});

我遇到的问题是模拟调用的测试通过了,但结果值没有通过。它表明它在预期值为 20、40、60 时返回 undefined。我不明白为什么模拟调用通过但结果值不通过。

我怀疑这是因为该函数位于另一个模块中,因为如果我像这样在测试中定义函数,则测试通过:

const myMockFn = jest.fn(n => n * 2);

test("map calls functions correctly", () => {
  const a = [10, 20, 30];

  a.map(myMockFn);

  expect(myMockFn.mock.calls.length).toBe(3);
  expect(myMockFn.mock.calls[0]).toEqual([10, 0, a]);
  expect(myMockFn.mock.calls[1]).toEqual([20, 1, a]);
  expect(myMockFn.mock.calls[2]).toEqual([30, 2, a]);
  expect(myMockFn.mock.results[0].value).toBe(20);
  expect(myMockFn.mock.results[1].value).toBe(40);
  expect(myMockFn.mock.results[2].value).toBe(60);
});

任何帮助/反馈将不胜感激!谢谢!

标签: javascriptunit-testingmockingjestjs

解决方案


jest.fn()将创建一个模拟函数,但它不会调用实际函数。您可以提供一个模拟实现,就像您在测试通过的场景中所做的那样。

但是,您不应该模拟您尝试测试的模块。

如果您需要检查函数的行为,最好调用函数本身并断言返回值。

const res = doubling(20)
expect(res).toEqual(40)

像上面这样的东西对你的模块来说是一个干净而清晰的测试。我不确定您是否有理由尝试检查函数的参数,但您需要调用实际函数或提供虚拟实现以在结果中获取一些值。


推荐阅读