3

我正在尝试为使用微前端架构的 react spa web 应用程序编写单元测试。我的第一步是为应用程序容器编写单元测试。

应用程序容器 react 组件使用一个 react-router 包含一个带有后续路由的开关来呈现主要内容区域中的组件。

每个应用程序都使用 JavaScript 运行时集成安装到应用程序容器。

我正在使用 React-Testing-Library 和 Jest 作为我的测试工具集的一部分。

我在互联网上到处搜索,没有找到任何关于我遇到的问题的有用文章。他们中的大多数都展示了一个测试与我的场景无关的 Web 应用程序的演示。

我有 3 个问题需要一些指导。

  1. 由于微前端由多层组件组成,这些组件与身份验证和其他业务逻辑链接在一起。我应该只测试“页面组件”吗?还是应该从 App 组件开始测试整个应用程序容器?如果两者都不是真的,我应该如何测试这个应用程序?

  2. 我尝试在页面组件级别进行测试以避免身份验证问题并且为了简单起见,但是该组件包含来自 React Router 库的组件,并且 Jest 抱怨我不应该使用<Link>未包含在组件中的<Router>组件。但是,<Router>在运行时执行时,组件存在于父组件级别。我怎样才能告诉 Jest “忽略”这个问题?

    我找不到允许我忽略此错误的配置。

  3. 由于问题 #2,我尝试通过渲染<App>组件来编写单元测试,但是该组件被传递到执行身份验证验证的高阶组件中。我怎样才能专注于测试最终结果而不是身份验证 HOC 的功能,以便我可以让组件呈现并让我的测试执行?

4

1 回答 1

1

通常,您应该测试每个组件,并且您应该只对包含在该组件中的逻辑进行断言

例如,假设您的 App 组件如下所示:

const App = () => (
   return (
     <Router>
       <Provider store={store}>
         <ThemeProvider>
            <Main/> <- the main entry point to your application
         </ThemeProvider>
       </Provider>
     </Router>
   );
);

然后,您需要在 App 的测试套件中验证的唯一一件事是您正在呈现正确的层次结构。即您不在乎App组件测试中包含的Main内容,您只关心App渲染Main

那么如何做到这一点呢?在您的测试套件中模拟Main组件并确保您的模拟呈现在层次结构中的正确位置。您还需要确保它使用正确的(可能是模拟的)和 a呈现Routera 。同样,这些组件中的每一个的内容并不重要,只是 App 将它们呈现在适当的层次结构中这一事实,因为这是包含的唯一逻辑。ProviderstoreThemeProviderApp

一旦您开始跨越边界并尝试验证Main. )。AppMainApp

我上面描述的是一种浅层渲染测试策略。有些人反对这种策略(甚至 react-testing-library 本身也不提倡它)。我有相当多的编写和测试反应代码的经验,绝对提倡浅渲染/组件模拟。当然,每种情况都是独一无二的,它可能并不总是最好的策略,但在我遇到的几乎所有情况下,它都允许您将逻辑封装到可测试的块中,并使事情很容易删除/重构。

我尝试在页面组件级别进行测试以避免身份验证问题并且为了简单起见,但是该组件包含来自 React Router 库的组件,并且 Jest 抱怨我不应该使用未包含在组件中的组件。但是,在运行时执行时,组件存在于父组件级别。我怎样才能告诉 Jest “忽略”这个问题?

这是一个非常常见的场景,解决方案是提供您的组件在测试设置中工作所需的依赖项。

如果您的组件需要某个上下文(例如Link需要 a NavigationContext),那么您的工作就是在 test setup 中提供该上下文

如果您的组件需要包装在路由器中,那么您的测试设置如下所示:

import { render, screen } from '@testing-library/react' 
import { Router } from 'react-router-dom';
import { MySubjectComponent } from './MySubjectComponent';

it('should show my component with a Link',() => {
  // provide a Router in the test fixture because you
  // know MySubjectComponent needs it
  render(
    <Router>
      <MySubjectComponent/>
    </Router>
  );
});

我怎样才能专注于测试最终结果而不是身份验证 HOC 的功能,以便我可以让组件呈现并让我的测试执行?

无论您尝试测试什么,答案总是相同的 - 模拟依赖项。

不过请小心。我可能会提倡将组件与它们在 HOC 中的行为分开测试。请记住,HOC 的唯一工作是为组件提供 props。您可以轻松地将这些道具直接提供给测试套件中的组件,以查看它的行为方式,而无需使用 HOC。

要测试 HOC,您需要模拟 HOC 的依赖项(用于执行身份验证的函数、请求和响应)并传入一个模拟组件,您可以对 HOC 传递的 props 进行简单断言给它。

好的测试是我可以谈论几周的事情。

于 2021-08-09T01:27:11.470 回答