为啥 jest 不能为我正在测试的自定义 React 钩子提供 useTranslation 钩子?

Posted

技术标签:

【中文标题】为啥 jest 不能为我正在测试的自定义 React 钩子提供 useTranslation 钩子?【英文标题】:Why is jest not able to provide the useTranslation hook to a custom React hook I'm testing?为什么 jest 不能为我正在测试的自定义 React 钩子提供 useTranslation 钩子? 【发布时间】:2021-12-14 08:11:03 【问题描述】:

我正在为自定义挂钩创建测试并检查它是否正确解析数据。自定义挂钩使用 i18next useTranslation 挂钩。我以这种方式模拟了测试文件中的 useTranslation 钩子:

jest.mock('react-i18next', () => (
  useTranslation: () => 
    return 
      t: (key: string) => key,
    
  ,
))

它没有给我任何错误,它只是不翻译并返回它必须翻译的字段上的本地化键。我是在嘲笑错误的方式还是应该做一些额外的配置?

【问题讨论】:

难道你不希望它不翻译而是返回本地化键,因为这正是你的模拟正在做的事情? 这肯定是问题的一部分,但是我认为我没有看到任何其他模拟 t() 函数的方法。有什么想法吗? 我不知道您的自定义挂钩是做什么的,但这就是您对测试感兴趣的内容。也许发布您的自定义钩子给我们一个想法,我们也许可以指导您。 【参考方案1】:

我认为对模拟和测试目的存在误解。

据开玩笑documentation:

Mock 函数允许您通过擦除函数的实际实现、捕获对函数的调用(以及在这些调用中传递的参数)、在使用 new 实例化时捕获构造函数的实例以及允许测试来测试代码之间的链接- 返回值的时间配置。

如果您想测试 useTranslation 挂钩的功能,您可以创建一个测试(无需模拟)。通过这种方式,您可以在不同的场景下测试您的钩子功能和行为。

现在回到你的代码,如果你想测试一个使用外部函数的组件,你可以模拟这个函数并将它传递给组件。所以在这种情况下,你只需要模拟这个函数并写一些关于它的异常。

例如,你有一个表单组件,它有一个提交按钮,随着提交,数据将被发送到服务器,所以你可以模拟这个提交动作并将它传递给测试环境的组件,那么你期望通过点击提交按钮,处理函数调用一次。

所以如果你想模拟你的钩子,你需要为它返回模拟数据:

const mockMyHook = jest.fn(x => 'translated');

现在在您的组件中调用这个模拟飞节,并期望输入 x,得到一个 tanslated 值。

【讨论】:

以上是关于为啥 jest 不能为我正在测试的自定义 React 钩子提供 useTranslation 钩子?的主要内容,如果未能解决你的问题,请参考以下文章

使用 SetTimeout 测试自定义钩子,使用 Jest 测试 useEffect

如何使用反冲为自定义钩子编写测试代码

为啥这些 Jest 测试失败了? TypeError:无法读取未定义的属性“应用”

调度自定义事件并测试它是不是被正确触发(React TypeScript,Jest)

用 jest 测试 redux 异步动作创建者

为啥 Jest 不让我使用节点测试环境,即使他们自己更改了它?