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

IT技术 reactjs unit-testing mocking jestjs enzyme
2021-04-26 02:15:13

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

import ComponentToMock from './ComponentToMock';

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

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

我知道我可以用类似的东西模拟一个直接的组件:

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

然而,由于这个组件通常会接收 props,React 会感到不安,给出一个关于未知 props(在这种情况下,testProp)被传递给 的警告<ComponentToMock />

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

所以我的问题是我怎么能

a)ComponentToMock忽略传递给它的props,或者

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

或者,还有更好的方法?

4个回答

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

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

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

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

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

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

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

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

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

注意:在撰写本文时,似乎必须调用该文件夹__mocks__(您需要__mocks__在每个需要模拟组件的文件夹中创建。如果下划线让您感到不安,请假装它们不存在;))

接下来,在这个模拟文件中,您可以根据需要编写文件,例如

// 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()没有第二个函数参数的 a 时,它会自动查找__mocks__文件夹。然而,即使在被测试的组件中提升了 mock 语句,这也不会影响 mock 本身的导入 - 这就是为什么它能够导入和编译 React 组件的原因!

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

除了已接受的答案,如果您使用多个导出,则可以按如下方式进行模拟:

// Component.jsx

export { A, B };
// Component-test.js

jest.mock("../src/Component", () => {
  return {
    A: true,
    B: () => {
      return <></>;
    },
  };
})

参考博客:https : //thoughtbot.com/blog/mocking-react-components-with-jest

就我而言,我无法使模拟工作。

结果证明是区分大小写的问题:

module文件名: Autosuggest.js

我是如何嘲笑它的:jest.mock('./AutoSuggest', ...); <-- 错误的情况