0

0

测试 ReactJS 上下文 - 测试替身指南

聖光之護

聖光之護

发布时间:2024-12-04 08:39:13

|

725人浏览过

|

来源于dev.to

转载

在这篇文章中,我将逐步介绍使用测试库测试依赖于上下文的 react 组件的思维过程。我的目标是探索一种不同的方法来测试这些组件,检查使用模拟与不模拟上下文的测试的优缺点。我们将研究每种方法如何影响测试的可靠性,并且我将分享关于何时以及为什么一种方法在实际应用中可能比另一种方法更有益的见解。

你应该知道什么

  • reactjs 是用来做什么的(可能你已经写过一些应用了)
  • 什么是 vitest

什么是反应上下文

reactjs 上下文的出现是为了解决 reactjs 组件结构中的一个常见问题:道具钻探。当我们有一系列组件需要访问同一组数据时,就会发生道具钻探。上下文机制允许组件共享同一组数据,只要上下文本身是第一个后代。

在reactjs文档中,使用了保存主题的上下文,因为其他组件可能需要此信息,文档使用上下文来处理该信息,而不是通过道具传递值。另一个示例是使用上下文来保存应用程序的布局,在 json-tool 示例中,app.tsx 使用可用于所有应用程序的 defaultlayout 上下文来包装应用程序。

本示例的应用程序

下面的示例将使用主题应用程序。它是一个允许用户在浅色/深色主题之间切换的应用程序。该应用程序也在reactjs官方文档中使用。该应用程序由一个简单的开关组成,可以在浅色主题模式和深色主题模式之间切换。该应用程序非常简单,我们可以将所有内容绘制在一个文件中:

import { createcontext, usecontext, usestate } from 'react'
const themecontext = createcontext('light')

function page() {
  const theme = usecontext(themecontext)
  return (
    

current theme: {theme}

) } function app() { const [theme, settheme] = usestate('light') return ( ) } export default app

在这个应用程序中,我们有两个主要组件:app 和 page。 app 组件作为主要组件,包含当前主题的状态,可以是“亮”或“暗”。它还包括一个可在浅色和深色模式之间切换主题的按钮。 page 组件是 app 的子组件,它使用主题上下文来显示当前主题。 app 组件中的按钮是一个简单的切换按钮,单击时会切换主题并相应地更新上下文值。

测试 ReactJS 上下文 - 测试替身指南

在下一节中,我们将讨论对组件进行切片以进行测试。

点火测试

通常在任何应用程序中,我们都必须专注于我们想要做什么样的测试,以及我们想要处理哪个部分。例如,我们可以针对单个组件,而不是整个应用程序。在我们的示例中,我们将从页面组件开始。这将需要我们使用测试替身来测试它。

测试 ReactJS 上下文 - 测试替身指南

测试替身来自应用程序结构本身,因为它取决于上下文,要更改它,上下文中的值也需要更改。

测试双打

为了开始使用 reactjs 中的上下文进行测试方法,我们将开始编写第一个测试:

import { render, screen } from '@testing-library/react'
import { page } from './page'

describe('', () => {
  it('should render light as default theme', () => {
    render()
    expect(screen.getbytext('current theme: light')).tobeinthedocument()
  })
})

鉴于浅色主题设置为 themecontext 中的默认主题,此测试将按预期通过。我们甚至可以测试第一个示例,但是,当我们对黑暗主题感兴趣时,第二个测试中的事情会变得有趣。为了进入黑暗主题,我们需要开始使用测试替身,因为我们依赖于 reactjs 上下文来做到这一点。第二个测试将 vi.mock 和 vi.mocked 混合在一起。请注意,要编写的第二个测试也需要更改第一个测试。

医院网站系统
医院网站系统

HTML医院网站系统基于PHP+MYSQL开发,在文章内容网站的基础上,预设了医院概况、新闻动态、环境设备、名医荟萃、专科介绍、就医指南、专家门诊值班表、网上挂号、医疗保健知识、在线咨询等医院网站常用的栏目和测试数据,采用适合医院网站的专用模版,增强了系统的针对性和易用性。系统具有文章、图文、下载、社区、表单、用户等基本系统模块和一系列网站辅助功能,用户也可根据自身特点任意创建和修改栏目,适合创建

下载
import { render, screen } from '@testing-library/react'
import { page } from './page'
import { usecontext } from 'react'

vi.mock('react', () => {
  return {
    ...vi.importactual('react'),
    usecontext: vi.fn(),
    createcontext: vi.fn()
  }
})

describe('', () => {
  it('should render light as default theme', () => {
    vi.mocked(usecontext).mockreturnvalue('light')
    render()
    expect(screen.getbytext('current theme: light')).tobeinthedocument()
  })

  it('should render dark theme', () => {
    vi.mocked(usecontext).mockreturnvalue('dark')
    render()
    expect(screen.getbytext('current theme: dark')).tobeinthedocument()
  })
})

两个测试用例现在都使用假的来测试驱动应用程序。如果我们改变上下文的返回数据,测试也会改变。这里的注意点是:

  • 我们正在嘲笑reactjs上下文,这违背了“不要嘲笑你不拥有的东西”的原则
  • 测试变得更加冗长,因为我们需要使用模拟来做到这一点
  • 我们编写的两个测试没有反映用户与应用程序的交互。我们知道,当按下切换按钮时,主题将会改变。
本节中使用的完整代码可在 github 上获取

没有测试替身

下一个方法是使用嵌入到我们的应用程序中的上下文,而不隔离它或使用任何测试替身。如果我们采用这种 tdd 方法,我们可以从一个非常简单的测试开始,模拟用户的行为方式:

import { render, screen } from '@testing-library/react'
import app from './app'
import userevent from '@testing-library/user-event'

describe('', () => {
  it('should render toggle button', () => {
    render()
    expect(screen.getbytext('toggle')).tobeinthedocument()
  })
})

然后进行第二个测试,我们希望默认设置灯光主题:

import { render, screen } from '@testing-library/react'
import app from './app'
import userevent from '@testing-library/user-event'

describe('', () => {
  it('should render toggle button', () => {
    render()
    expect(screen.getbytext('toggle')).tobeinthedocument()
  })

  it('should render light as default theme', () => {
    render()
    expect(screen.getbytext('current theme: light')).tobeinthedocument()
  })
})

最后但并非最不重要的主题切换:

import { render, screen } from '@testing-library/react'
import App from './App'
import userEvent from '@testing-library/user-event'

describe('', () => {
  it('should render toggle button', () => {
    render()
    expect(screen.getByText('Toggle')).toBeInTheDocument()
  })

  it('should render light as default theme', () => {
    render()
    expect(screen.getByText('current theme: light')).toBeInTheDocument()
  })

  it('should render dark theme on toggle', async () => {
    const user = userEvent.setup()
    render()

    await user.click(screen.getByText('Toggle'))

    expect(screen.getByText('current theme: dark')).toBeInTheDocument()
  })
})

本攻略注意点:

  • 不需要测试替身,它可以用更少的代码进行测试
  • 测试的行为与用户在真实应用程序中的行为相匹配
本节中使用的完整代码可在 github 上获取

每种方法的优缺点

在本节中,我们将讨论每种方法在不同属性方面的优缺点。

重构 props

在上下文中使用测试替身会使测试对于这种更改变得脆弱。使用 props 重构 usecontext 的使用会自动使测试失败,即使行为没有失败。使用不使用测试双精度的选项支持在这个意义上的重构。

创建自定义上下文

使用自定义上下文而不是直接依赖reactjs 的上下文提供程序也会发生同样的情况。使用不带测试替身的选项可以进行重构。

结论

在本指南中,我们探索了如何测试依赖于上下文的组件,而不需要测试替身,使测试更加简单,更接近真实的用户交互,并对比每种方法的优缺点。只要有可能,应遵循反映用户交互的简单方法。然而,当需要测试替身时,应该以测试代码的可维护性为目标来使用它们。通过简单的测试可以放心地重构生产代码。

资源

  • 创建自定义上下文
  • 重构目录
  • 用于查找如何使用 vitest 模拟模块的特定部分
  • 用于查找如何解决类型问题
  • 测试库 userevent

下一步

  • 尝试测试涉及多个上下文或嵌套提供程序的更复杂的场景。
  • 虽然我们在本指南中避免了模拟,但在某些情况下模拟是必要的。探索这些场景的高级模拟技术。

通过遵循这些步骤,您可以继续提高测试技能并确保您的 react 应用程序可以重构。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

415

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

533

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

310

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

75

2025.09.10

go语言 数组和切片
go语言 数组和切片

本专题整合了go语言数组和切片的区别与含义,阅读专题下面的文章了解更多详细内容。

46

2025.09.03

github中文官网入口 github中文版官网网页进入
github中文官网入口 github中文版官网网页进入

github中文官网入口https://docs.github.com/zh/get-started,GitHub 是一种基于云的平台,可在其中存储、共享并与他人一起编写代码。 通过将代码存储在GitHub 上的“存储库”中,你可以: “展示或共享”你的工作。 持续“跟踪和管理”对代码的更改。

2

2026.01.21

Java JVM 原理与性能调优实战
Java JVM 原理与性能调优实战

本专题系统讲解 Java 虚拟机(JVM)的核心工作原理与性能调优方法,包括 JVM 内存结构、对象创建与回收流程、垃圾回收器(Serial、CMS、G1、ZGC)对比分析、常见内存泄漏与性能瓶颈排查,以及 JVM 参数调优与监控工具(jstat、jmap、jvisualvm)的实战使用。通过真实案例,帮助学习者掌握 Java 应用在生产环境中的性能分析与优化能力。

19

2026.01.20

PS使用蒙版相关教程
PS使用蒙版相关教程

本专题整合了ps使用蒙版相关教程,阅读专题下面的文章了解更多详细内容。

61

2026.01.19

java用途介绍
java用途介绍

本专题整合了java用途功能相关介绍,阅读专题下面的文章了解更多详细内容。

87

2026.01.19

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Git 教程
Git 教程

共21课时 | 2.8万人学习

Git版本控制工具
Git版本控制工具

共8课时 | 1.5万人学习

Git中文开发手册
Git中文开发手册

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号