reactjs - 微前端 react 应用程序的单元测试

标签 reactjs micro-frontend react-testing

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

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

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

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。您可以轻松地将这些 Prop 直接提供给测试套件中的组件,以查看其行为方式,而无需使用 HOC。

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

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

关于reactjs - 微前端 react 应用程序的单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68705755/

相关文章:

unit-testing - 如何使用 Jest 和 enzyme 测试正在使用其他微前端组件的一个微前端组件

javascript - 多个客户端使用的 JavaScript 包的交付机制

twitter-bootstrap - 即使 showModal 设置为 true 后,React-bootstrap 模式也不会弹出

javascript - react .js : attach event from parent to children

reactjs - 使用 header 配方的 Apollo 授权不起作用

javascript - 类型 'XYZ' 上不存在属性 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'

angular - 在 Angular Web 组件内加载 native Web 组件(非 Angular 组件)