使用 Jest 模拟带有 props 的 React 组件

新手上路,请多包涵

我有一个 React 组件,其中包含一些其他组件,这些组件依赖于对 Redux 存储等的访问,这在执行完整的 Enzyme 安装时会导致问题。让我们说一个这样的结构:

 import ComponentToMock from './ComponentToMock';

<ComponentToTest>
  ...some stuff
  <ComponentToMock testProp="This throws a warning" />
</ComponentToTest>

我想使用 Jest 的 .mock() 方法来模拟子组件,这样就不用担心测试了。

我知道我可以模拟一个直接的组件,例如:

jest.mock('./ComponentToMock', () => 'ComponentToMock');

但是,由于该组件通常会接收道具,因此 React 会感到不安,并发出有关未知道具(在本例中为 testProp )被传递给 <ComponentToMock /> 的警告。

我试图返回一个函数,但是你不能在 Jest 模拟中返回 JSX(据我所知),因为它被提升了。在这种情况下会引发错误。

所以我的问题是我怎么能

a) 获取 ComponentToMock 忽略传递给它的道具,或者

b) 返回一个 React 组件,该组件可用于模拟我不担心测试的子组件。

或者,还有更好的方法?

原文由 Mike Hopkins 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.3k
2 个回答

文档底部有一条注释 jest.mock() 用于防止提升行为:

注意:当使用 babel-jest 时,对 mock 的调用将自动提升到代码块的顶部。如果您想明确避免这种行为,请使用 doMock

然后你可以按照你的描述做:返回一个函数,它是你不需要测试的组件的存根。

 jest.doMock('./ComponentToMock', () => {
  const ComponentToMock = () => <div />;
  return ComponentToMock;
});

const ComponentToTest = require('./ComponentToTest').default;

命名存根组件会很有帮助,因为它会在快照中呈现。

原文由 Mike Reifman 发布,翻译遵循 CC BY-SA 4.0 许可协议

自从我问了这个问题后,我学到了更多。这是处理需要传递道具的模拟组件的另一种(更好?)方法:使用模块 _模拟文件_。

首先在组件文件夹下的 __mocks__ 文件夹中创建一个与要模拟的组件同名的文件,例如

.
|- /ComponentToMock.js
└- /__mocks__/ComponentToMock.js <-- create this folder/file!

_注意_:在撰写本文时,该文件夹似乎 必须 被调用 __mocks__ (您需要创建 __mocks__ 在每个文件夹中您需要模拟组件。如果下划线打乱你,假装他们不存在 ;) )

接下来,在这个mock文件中,你可以随意编写文件,eg

 // This code would live in ./__mocks__/ComponentToMock.js
import React from 'react';
const ComponentToMock = ({ testProp }) => <div>A mock with '{testProp}' passed!</div>;
export default ComponentToMock;

然后在测试文件中,将 Jest mock 语句更改为: jest.mock('./ComponentToMock');

当 Jest 遇到没有第二个函数参数的 .mock() 时,它会自动查找 __mocks__ 文件夹。然而,即使 mock 语句在被测试的组件中被提升,这也不会影响 mock 本身的导入——这就是为什么它能够导入和编译 React 组件!

这似乎适用于需要传递 props 的模拟组件,否则会在返回空函数时产生 prop 警告(但如果组件未收到 props 则继续使用是完全可以接受的)。我希望这可以帮助一些人。

原文由 Mike Hopkins 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进