通常,您应该测试每个组件,并且您应该只对包含在该组件中的逻辑进行断言。
例如,假设您的 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呈现Router
a 。同样,这些组件中的每一个的内容并不重要,只是 App 将它们呈现在适当的层次结构中这一事实,因为这是包含的唯一逻辑。Provider
store
ThemeProvider
App
一旦您开始跨越边界并尝试验证Main
. )。App
Main
App
我上面描述的是一种浅层渲染测试策略。有些人反对这种策略(甚至 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 进行简单断言给它。
好的测试是我可以谈论几周的事情。