Jest 手动模拟在 CRA 中不使用模拟文件

Posted

技术标签:

【中文标题】Jest 手动模拟在 CRA 中不使用模拟文件【英文标题】:Jest manual mocks does not use mock file in CRA 【发布时间】:2021-03-14 09:53:46 【问题描述】:

我有一个 CRA 应用程序并尝试使用 Jest 的 manual mocks 功能,但我的手动模拟似乎没有应用。

我使用src 的基本网址(通过将其设置为tsconfig.json)。简化,我有并且有一个文件结构

src/
|- components/
|-- Foo/
|--- index.js
|--- Foo.jsx
|- App.js
|- App.test.js

其中App.js 使用import Foo from "components/Foo"。在App.test.js 中,我希望Foo 被嘲笑(它的计算量很大并且在单元测试中经过测试)。所以在我的测试中,我添加了jest.mock("components/Foo"),并在我绝望中添加了几个__mocks__ 文件夹,例如

__mocks__
|- components\
|-- Foo.jsx
src/
|- __mocks__/
|-- components/
|--- Foo.jsx
|- components/
|-- Foo/
|--- __mocks__
|---- Foo.js
|--- index.js
|--- Foo.jsx
|- App.js
|- App.test.js

每个手动模拟包含的位置

console.log("Mock imported");

export default function MyMock()
  console.log("Mock used");
  return <p />;

但是,在运行测试时,没有来自模拟的控制台打印输出,虽然 Foo 被分配了一个空模拟,但它没有使用预期的手动模拟。

我做错了什么?

【问题讨论】:

你也可以分享测试文件吗?另外,只要确保您在jest.mock() 中有相对路径,对吗?喜欢import SoundPlayer from './sound-player'; jest.mock('./sound-player'); // SoundPlayer is now a mock constructor 不,我在App.jsApp.test.js 中都使用绝对路径。这可能是导致问题的原因吗?使用相对路径很困难,因为我正在处理一个非常大的应用程序 【参考方案1】:

我发现您的文件结构不正确。 __mocks__ 目录应该直接在 components 下

src/
|- components/
|-- Foo.js 
|-- __mocks__
|--- Foo.jsx
|- App.js
|- App.test.js

现在主模块目录上的 Foo.js 可以是这样的

function Foo() 
    return (
     
       <h1> Foo</h1>
    );
  

  export default Foo;

而 __mocks/Foo.js 可以是

console.log("Mock imported");

function Foo() 
    return (
     
       <h1> Mock</h1>
    );
  

  export default Foo;

App.test.js 将包含 jest.mock 调用

import  render, screen  from '@testing-library/react';
import App from './App';


jest.mock("./components/Foo");

test('renders learn react link', () => 

 
  render(<App />);
  const linkElement = screen.getByText(/Mock/i); // Check that MOCK component is called
  expect(linkElement).toBeInTheDocument();
);

查看 git 存储库以获取工作示例 https://github.com/meera/jest_mock

【讨论】:

感谢您的回购。但是,如果Foo 是一个包含index.jsFoo.jsx 文件的文件夹,应该如何处理呢? index.js 包含 export default from "./Foo"; 我意识到__mocks__ 应该在Foo 文件夹中并包含一个index.js 文件。然后它按预期工作 @JohanBook 你是说需要有一个src/components/Foo/__mocks__/index.js 文件? 我更新了存储库 - 即使 Foo 是一个包含 index.js 和 Foo.jsx 文件的文件夹,它也应该可以工作。【参考方案2】:

创建模拟是一个 3 步过程:

    App.js import Foo from 'components/Foo' 中导入Foo/index.js。内部组件创建__mocks__/Foo/index.js 并导出模拟组件。 在项目根目录jest.setup.js 中为 jest 创建一个安装文件并声明jest.mock('src/components/Foo') 在 jest 配置中,添加选项 setupFilesAfterEnv: ['./jest.setup.js']

【讨论】:

我将__mocks__ 文件夹直接放在Foo 文件夹中,index.js__mocks__ 中,然后它按预期工作。 是的,mocks目录中mock文件的文件路径要与父目录完全匹配。

以上是关于Jest 手动模拟在 CRA 中不使用模拟文件的主要内容,如果未能解决你的问题,请参考以下文章

使用 Typescript 从 Jest 手动模拟中导入函数

使用 Jest 手动模拟 React-Intl 进行快照测试

Jest - 模拟函数,从另一个文件导入

jest.mock():如何使用工厂参数模拟 ES6 类默认导入

Jest - 模拟和测试 node.js 文件系统

如何使用 Jest 模拟异步函数