微前端反应应用程序的单元测试

Unit testing for micro-frontend react application

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

应用程序容器 React 组件使用一个 React-Router 包含一个带有后续路由的开关来渲染主要内容区域中的组件。

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

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

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

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

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

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

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

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

一般来说,您应该测试每个组件并且您应该只对包含在该组件中的逻辑做出断言

例如,假设您的 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 组件,并确保您的模拟呈现在层次结构中的正确位置。您还需要确保它使用正确的(可能是模拟的 store)和 ThemeProvider 呈现 RouterProvider。同样,每个组件的内容并不重要,重要的是 App 在适当的层次结构中呈现它们这一事实,因为这是 App 包含的唯一逻辑。

一旦您开始跨越边界并尝试在 App 的测试套件中验证 Main 的内容,那么它很快就会变得非常笨拙 - 即如果您更改Main 你最终会破坏你的 App 测试,这是错误的 (IMO)。

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

I tried to test on the page component level to avoid authentication issues and for simplicity sake, but the component contains a component from React Router library, and Jest is complaining that I should not be using component that isn't enclosed within a component. However, the component is present at the parent component level when executed in runtime. How can I tell Jest to "ignore" this problem?

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

如果您的组件需要特定的上下文(例如 Link 需要 NavigationContext),那么您的工作就是在测试设置中提供该上下文 .

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

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>
  );
});

How can I focus on testing the end result instead of the functionality of the authentication HOC just so I can get the component to render and for my tests to execute?

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

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

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

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