跨测试重用 Jest 模块模拟

Posted

技术标签:

【中文标题】跨测试重用 Jest 模块模拟【英文标题】:Reuse Jest module mocks across tests 【发布时间】:2021-08-27 15:21:00 【问题描述】:

我想模拟一个模块进行测试。一切正常,但我必须将相同的代码复制/粘贴到每个测试文件中。我怎样才能使它更易于维护?

(这是在 Next.js 项目中使用 Babel 和 TypeScript。)

生产代码如下所示:

import  useRouter  from 'next/router';

// Then call the hook in a React component:
  const router = useRouter();

测试代码:

// I need to access these mocks in the tests
const mockRouterPush = jest.fn();
const mockRouterBack = jest.fn();

jest.mock('next/router', () => (
  useRouter: () => (
    push: mockRouterPush,
    query:  segment: 'seg1' ,
    back: mockRouterBack,
  ),
));

这很好用。模块及其钩子是为测试文件模拟的,我可以参考测试中的模拟。问题是很难跨多个测试文件进行维护。

对jest.mock() 的调用被提升到文件的顶部,并且只能引用以单词“mock”开头的变量。

对于其他模拟,我在模块工厂中使用了require,而不是import;这有效并减少了样板文件,但是(a)使测试更难以引用模拟,并且(b)我的 IDE(VSCode)不会像我移动文件时那样自动更新需要路径。例如:

jest.mock('react-i18next', () => 
  // Sometimes the path is '../../../testhelpers' etc.
  const  mockUseTranslation  = require('./testhelpers');

  return 
    useTranslation: mockUseTranslation,
  ;
);

我试过doMockcreateMockFromModule 都没有成功。

其他人如何处理这个问题?

【问题讨论】:

【参考方案1】:

也许使用__mock__ 目录可以帮助你。

来自文档:

手动模拟是通过在紧邻模块的 mocks/ 子目录中编写模块来定义的。例如,要在 models 目录中模拟一个名为 user 的模块,请创建一个名为 user.js 的文件并将其放在 models/mocks 目录中。

您还可以模拟 node_modules 目录中的模块。

Manual Mocks

【讨论】:

谢谢!一位同事也提到了这一点,我刚刚尝试成功。嵌套工作: __mocks__/next/router.js 然后只需 jest.mock('next/router') 要访问模拟,我可以在测试中使用 import useRouter from 'next/router',然后 const push: mockRouterPush = useRouter()(禁用钩子规则)。

以上是关于跨测试重用 Jest 模块模拟的主要内容,如果未能解决你的问题,请参考以下文章

跨junit测试类重用spring应用程序上下文

JMeter - 如何创建可重用和模块化测试脚本

使用 JEST 和 nock 进行测试导致“禁止跨源 null”

如何创建和维护代码重用库?

如何重用 Angular 测试文件中的所有导入

用 Jest 模拟 Lerna 范围模块