0

0

怎样编写可测试的JavaScript代码以及有哪些最佳实践?

夢幻星辰

夢幻星辰

发布时间:2025-09-25 10:49:01

|

282人浏览过

|

来源于php中文网

原创

编写可测试的JavaScript代码需在设计时注重高内聚、低耦合。1. 优先使用纯函数处理逻辑,将副作用操作隔离;2. 避免全局状态,通过参数注入依赖如时间或随机值;3. 采用依赖注入解耦服务,便于模拟API等外部依赖;4. 模块化拆分职责单一的函数和模块,提升测试专注度;5. 异步代码应返回Promise并支持可控延迟,方便测试跳过时间依赖;6. 使用Jest等现代测试工具,结合mock和jsdom模拟环境。核心是确保代码行为可预测、依赖可替换、逻辑可分割,从而实现高效可靠的单元测试。

怎样编写可测试的javascript代码以及有哪些最佳实践?

编写可测试的JavaScript代码关键在于让代码具备高内聚、低耦合、职责清晰和易于模拟依赖的特点。测试友好性不是事后添加的,而是设计时就要考虑的。以下是具体做法和最佳实践。

1. 函数应保持纯函数或明确副作用

纯函数是指相同的输入始终产生相同的输出,并且不修改外部状态。这类函数最容易测试。

建议:
  • 尽量将逻辑封装在无副作用的函数中,比如数据处理、格式转换等。
  • 将有副作用的操作(如DOM操作、API调用、localStorage)隔离到单独的函数或模块。
  • 例如:

可测试写法:

function calculateTax(amount, rate) {
  return amount * rate;
}

function saveUserToStorage(user) { localStorage.setItem('user', JSON.stringify(user)); }

第一个函数可以直接断言结果;第二个虽然有副作用,但职责单一,便于通过模拟 localStorage 来测试。

立即学习Java免费学习笔记(深入)”;

2. 避免全局状态和隐式依赖

全局变量或隐式依赖(如直接使用 Date、Math.random)会使测试不可靠,因为它们难以控制。

建议:
  • 通过参数传入依赖,而不是在函数内部直接引用。
  • 例如,不要在函数里直接用 new Date(),而是接受一个时间戳或日期对象。

改进示例:

// 不推荐
function isToday(dateString) {
  const today = new Date();
  const inputDate = new Date(dateString);
  return today.toDateString() === inputDate.toDateString();
}

// 推荐:允许注入当前时间 function isToday(dateString, now = new Date()) { const inputDate = new Date(dateString); return now.toDateString() === inputDate.toDateString(); }

测试时可以传入固定的 now 值,避免因时间变化导致测试失败。

3. 使用依赖注入解耦模块

当函数或类依赖外部服务(如API客户端、数据库)时,应通过参数传入,而不是在内部创建。

PictoGraphic
PictoGraphic

AI驱动的矢量插图库和插图生成平台

下载
建议:
  • 构造函数或函数参数接收依赖项,便于替换为模拟对象(mock)。
  • 例如:
class UserService {
  constructor(apiClient) {
    this.apiClient = apiClient;
  }

async getUser(id) { const response = await this.apiClient.get(/users/${id}); return response.data; } }

测试时可以传入一个模拟的 apiClient,验证调用行为而不发真实请求。

4. 模块化设计,单一职责

每个文件或函数只做一件事。这样测试用例更专注,维护也更容易。

建议:
  • 拆分大函数为小函数,每个函数完成一个明确任务。
  • 使用 ES 模块或 CommonJS 明确导出可测试的部分。
  • 避免在一个文件中混合逻辑、DOM操作和事件绑定。

例如,把表单验证逻辑独立出来,而不是写在事件回调里。

5. 编写可预测的异步代码

异步操作(Promise、async/await)是测试难点,关键是让它们可控制。

建议:
  • 返回 Promise 的函数应始终处理错误,避免未捕获异常。
  • 使用 setTimeout 的场景,考虑将其抽象为可配置的延迟函数,方便测试跳过。
  • 测试异步代码时,使用 done 回调或 async/await 断言。

示例:

function delay(ms, callback) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(callback());
    }, ms);
  });
}

测试时可将 ms 设为 0 或 mock setTimeout。

6. 使用测试友好的工具和结构

选择合适的测试框架和辅助工具能大幅提升效率。

建议:
  • 使用 Jest、Vitest 等现代测试框架,支持快照、mock、覆盖率报告。
  • 利用 beforeEach 和 afterEach 隔离测试上下文。
  • 对 DOM 操作使用 jsdom 或 Testing Library 进行模拟。
  • 为第三方库(如 fetch、axios)设置 mock 实现。

基本上就这些。核心是让代码行为可预测、依赖可替换、逻辑可分割。只要设计时多花一点心思,后续测试就会轻松很多。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
全局变量怎么定义
全局变量怎么定义

本专题整合了全局变量相关内容,阅读专题下面的文章了解更多详细内容。

78

2025.09.18

python 全局变量
python 全局变量

本专题整合了python中全局变量定义相关教程,阅读专题下面的文章了解更多详细内容。

96

2025.09.18

DOM是什么意思
DOM是什么意思

dom的英文全称是documentobjectmodel,表示文件对象模型,是w3c组织推荐的处理可扩展置标语言的标准编程接口;dom是html文档的内存中对象表示,它提供了使用javascript与网页交互的方式。想了解更多的相关内容,可以阅读本专题下面的文章。

3309

2024.08.14

promise的用法
promise的用法

“promise” 是一种用于处理异步操作的编程概念,它可以用来表示一个异步操作的最终结果。Promise 对象有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。Promise的用法主要包括构造函数、实例方法(then、catch、finally)和状态转换。

306

2023.10.12

html文本框类型介绍
html文本框类型介绍

html文本框类型有单行文本框、密码文本框、数字文本框、日期文本框、时间文本框、文件上传文本框、多行文本框等等。详细介绍:1、单行文本框是最常见的文本框类型,用于接受单行文本输入,用户可以在文本框中输入任意文本,例如用户名、密码、电子邮件地址等;2、密码文本框用于接受密码输入,用户在输入密码时,文本框中的内容会被隐藏,以保护用户的隐私;3、数字文本框等等。

406

2023.10.12

数据库三范式
数据库三范式

数据库三范式是一种设计规范,用于规范化关系型数据库中的数据结构,它通过消除冗余数据、提高数据库性能和数据一致性,提供了一种有效的数据库设计方法。本专题提供数据库三范式相关的文章、下载和课程。

358

2023.06.29

如何删除数据库
如何删除数据库

删除数据库是指在MySQL中完全移除一个数据库及其所包含的所有数据和结构,作用包括:1、释放存储空间;2、确保数据的安全性;3、提高数据库的整体性能,加速查询和操作的执行速度。尽管删除数据库具有一些好处,但在执行任何删除操作之前,务必谨慎操作,并备份重要的数据。删除数据库将永久性地删除所有相关数据和结构,无法回滚。

2082

2023.08.14

vb怎么连接数据库
vb怎么连接数据库

在VB中,连接数据库通常使用ADO(ActiveX 数据对象)或 DAO(Data Access Objects)这两个技术来实现:1、引入ADO库;2、创建ADO连接对象;3、配置连接字符串;4、打开连接;5、执行SQL语句;6、处理查询结果;7、关闭连接即可。

349

2023.08.31

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

158

2026.01.28

热门下载

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

精品课程

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

共58课时 | 4.2万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.5万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3万人学习

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

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