使用Jest使用props模拟React组件

时间:2017-06-07 03:49:59

标签: reactjs unit-testing mocking jestjs enzyme

我有一个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组件,该组件可用于模拟我不担心测试的子组件。

或者......有更好的方法吗?

4 个答案:

答案 0 :(得分:11)

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

  

注意:使用babel-jest时,系统会自动拨打mock   提升到代码块的顶部。如果您愿意,请使用doMock   明确避免这种行为。

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

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

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

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

答案 1 :(得分:4)

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

首先在组件文件夹下的__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模拟语句更改为:jest.mock('./ComponentToMock');

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

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

答案 2 :(得分:1)

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

// 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

答案 3 :(得分:-1)

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

一个事实是区分大小写的问题:

模块文件名:Autosuggest.js

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