为啥 react-test-renderer 在 React 中只能在同一个文件中 findByType 功能组件?

Posted

技术标签:

【中文标题】为啥 react-test-renderer 在 React 中只能在同一个文件中 findByType 功能组件?【英文标题】:Why can react-test-renderer only findByType functional components in the same file in React?为什么 react-test-renderer 在 React 中只能在同一个文件中 findByType 功能组件? 【发布时间】:2021-09-27 19:54:24 【问题描述】:

这是我正在测试的功能组件some-table.jsx

import React from 'react';

const SomeTable = ( somethings ) => (
  <>
    somethings.map(something => 
      return <SomeRow key=something something=something />
    )
  </>
);

export const SomeRow = ( something ) => 
  return <p>something</p>


export default SomeTable;

这是我的测试文件:

import  create  from "react-test-renderer";
import SomeTable,  SomeRow  from "../common/ui/some-table";

test("check SomeTable has row", () => 
  const renderer = create(<SomeTable somethings=["Hello", "World"] />);
  const allRows = renderer.root.findAllByType(SomeRow);
  expect(allRows.length).toBe(2);
);

此测试通过。但是,如果我将 SomeRow 移动到它自己的文件中,它就会失败:

some-table.jsx:

import React from 'react';
import  SomeRow  from './some-row';

const SomeTable = ( somethings ) => (
  <>
    somethings.map(something => 
      return <SomeRow key=something something=something />
    )
  </>
);

export default SomeTable;

some-row.jsx:

import React from 'react';

export const SomeRow = ( something ) => 
  return <p>something</p>

失败:

expect(received).toBe(expected) // Object.is equality

Expected: 2
Received: 0

任何想法为什么会这样?感谢您的阅读。

【问题讨论】:

【参考方案1】:

在创建这些Some...测试文件来解决的实际场景中,问题是由React的memo()函数引起的:

import React,  memo  from 'react';
...
export default memo(SomeRow);

一种解决方法如下:

const allRows = renderer.root.findAllByType(SomeRow.type);

道具bensampaiofor that tip。您还会发现很多其他讨论 on that link 可能对您有所帮助,包括:

reactreact-domreact-test-renderer 固定到16.11.0,最重要的是添加对react-is@16.11.0 的依赖关系,或使用如下谓词:

const elementByType = (type) => (element) => (
    element.type === type // Match non-memo'd
    || element.type === type.type // Match memo'd
);

还应该指出,我也做了一些愚蠢的事情。进口是错误的。这个:

import SomeTable,  SomeRow  from "../common/ui/some-table";

应该是这样的:

import SomeTable from "../common/ui/some-table";
import  SomeRow  from "../common/ui/some-row";

【讨论】:

以上是关于为啥 react-test-renderer 在 React 中只能在同一个文件中 findByType 功能组件?的主要内容,如果未能解决你的问题,请参考以下文章

使用带有样式组件和主题的 react-test-renderer (React Native)

如何使用react-test-renderer和jest测试包含嵌套组件的反应组件?

模拟阿波罗链路状态

IDE 无法识别 Jest 及其功能

使用 Hooks 在 React 中对 Apollo Graphql 进行单元测试

运行测试时获取“不变违规:本机模块不能为空。”