”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 了解干净的代码:单元测试 ⚡

了解干净的代码:单元测试 ⚡

发布于2024-08-31
浏览:188

Understanding Clean Code: Unit Tests ⚡

在软件开发中,单元测试是一种至关重要的实践,有助于确保代码的正确性。

《干净的代码:敏捷软件工艺手册》的第 9 章,标题为“单元测试”,深入探讨了编写干净且有效的单元测试的原则和实践。

在本文中,我们将总结本章的要点,并提供 JavaScript 示例来说明这些概念。


?为什么单元测试很重要

单元测试涉及为代码的各个单元或组件编写测试,以验证它们是否按预期运行。单元测试的主要目标是:

1- 及早检测错误: 在开发过程中发现问题,然后再投入生产。

2- 促进重构:确保对代码的更改不会破坏现有功能。

3- 文档代码行为: 作为如何使用代码的文档。


?有效单元测试的原则

⚡ 一次测试一件事

每个单元测试应该关注功能的一个方面。这使得测试更容易理解和维护。如果测试失败,您就会确切地知道问题出在哪里。

function add(a, b) {
    return a   b;
}

// Test case for the add function
function testAdd() {
    // Test adding positive numbers
    assertEqual(add(2, 3), 5, '2   3 should be 5');
    // Test adding negative numbers
    assertEqual(add(-1, -1), -2, '-1   -1 should be -2');
}

// A simple assertion function
function assertEqual(actual, expected, message) {
    if (actual !== expected) {
        throw new Error(message);
    }
}

⚡ 使测试可读

您的测试应该易于阅读和理解。为您的测试函数使用描述性名称和清晰的断言。这有助于其他人(和您自己)快速掌握每个测试正在验证的内容。

function isEven(number) {
    return number % 2 === 0;
}

// Descriptive test function
function testIsEven() {
    assertEqual(isEven(4), true, '4 should be even');
    assertEqual(isEven(5), false, '5 should be odd');
}

⚡ 使用清晰且具有描述性的名称

测试用例的名称应该描述他们正在测试的内容。这增强了测试的可读性和可维护性。

function calculateTotalPrice(items) {
    return items.reduce((total, item) => total   item.price, 0);
}

// Descriptive test case names
function testCalculateTotalPrice() {
    assertEqual(calculateTotalPrice([{ price: 10 }, { price: 20 }]), 30, 'Total price should be 30 for items costing 10 and 20');
    assertEqual(calculateTotalPrice([{ price: 5 }]), 5, 'Total price should be 5 for a single item costing 5');
}

⚡ 保持测试独立

每个测试应该独立于其他测试。依赖共享状态的测试可能会导致不稳定的测试并使调试变得困难。

function multiply(a, b) {
    return a * b;
}

// Independent test cases
function testMultiply() {
    assertEqual(multiply(2, 3), 6, '2 * 3 should be 6');
    assertEqual(multiply(0, 10), 0, '0 * 10 should be 0');
}

⚡ 适当使用模拟和存根

模拟和存根可以通过模拟依赖关系来帮助隔离被测代码单元。但是,请谨慎使用它们以避免测试过于复杂。

// Example of using a mock for a database call
function getUser(id) {
    // Imagine this function makes a database call
    return database.getUserById(id);
}

function testGetUser() {
    const mockDatabase = {
        getUserById: (id) => ({ id, name: 'John Doe' }),
    };

    const result = getUser(1, mockDatabase);
    assertEqual(result.name, 'John Doe', 'User name should be John Doe');
}

⚡ 自动化测试

自动运行单元测试以确保它们定期执行。持续集成 (CI) 工具可以帮助您在发生更改时自动运行测试。

如果您使用 Jest 这样的测试框架,您可以在 package.json 中设置脚本:

"scripts": {
    "test": "jest"
}

运行 npm test 将执行所有测试并提供有关其状态的反馈。


结论

编写干净有效的单元测试对于维护高质量代码至关重要。

通过遵循 Clean Code 第 9 章中概述的原则,您可以确保您的测试可靠、可理解且有价值。

在 JavaScript 代码中实现这些实践不仅可以提高测试质量,还有助于构建更健壮且可维护的代码库。

快乐编码!

版本声明 本文转载于:https://dev.to/alisamir/understanding-clean-code-unit-tests-5d1a?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 如何使用 Docker Scratch 在 Golang 中创建静态二进制文件:CGO_ENABLED=0 和 -ldflags?
    如何使用 Docker Scratch 在 Golang 中创建静态二进制文件:CGO_ENABLED=0 和 -ldflags?
    在 Golang 中创建静态二进制文件的标志当使用 Docker 临时库在 Golang 中构建静态二进制文件时,必须包含 CGO_ENABLED =0 和 -ldflags '-extldflags "-static"' 标志。虽然这两个选项可能看起来多余,但它...
    编程 发布于2024-11-06
  • 我可以将行追加到 CSV 文件而不覆盖它吗?
    我可以将行追加到 CSV 文件而不覆盖它吗?
    在 Python 中向现有 CSV 文件追加新行:一种更有效的方法当您需要使用附加行更新 CSV 文件时,您可能会考虑以下问题:问: 是否可以向现有 CSV 文件添加新行,而无需覆盖和重新创建文件?答: 绝对!以下是将行追加到 CSV 文件的更有效方法:您可以利用Python 中的 with 语句。...
    编程 发布于2024-11-06
  • Nestjs、Firebase、GCloud。如何在 TypeScript 中快速设置 API 后端。
    Nestjs、Firebase、GCloud。如何在 TypeScript 中快速设置 API 后端。
    It's great that you decided to open this article. My name is Fedor, and I've been a full-stack developer on a permanent basis since the end of 2021. J...
    编程 发布于2024-11-06
  • 如何在维护异步操作的同时避免链式函数中的 jQuery Promise?
    如何在维护异步操作的同时避免链式函数中的 jQuery Promise?
    在链式函数中回避 jQuery Promise尽管建议避免 jQuery Promise,但开发人员在不使用 jQuery 的情况下链接异步 jQuery 函数时可能会面临挑战Promise 处理机制,如 .then() 或 .when()。为了解决这个问题,请考虑以下方法:jQuery Promi...
    编程 发布于2024-11-06
  • 为什么“repr”方法在 Python 中至关重要?
    为什么“repr”方法在 Python 中至关重要?
    探索repr方法的意义在Python编程的上下文中,repr 方法在将对象表示为字符串方面起着关键作用。这种简洁而详细的表示有多种用途:repr的目的方法:repr的主要目标方法的目的是返回一个对象的字符串表示形式,该对象既是人类可读的,而且重要的是,是明确的。这种表示应该足以重新创建具有相同状态和...
    编程 发布于2024-11-06
  • 每个开发人员都应该了解可扩展和高效应用程序的顶级 React 设计模式
    每个开发人员都应该了解可扩展和高效应用程序的顶级 React 设计模式
    随着 React 继续主导前端生态系统,掌握其设计模式可以显着提高应用程序的效率和可扩展性。 React 设计模式提供了组织和构建组件、管理状态、处理 props 和提高可重用性的最佳实践。在本博客中,我们将探讨一些关键的 React 设计模式,这些模式可以使您的开发过程从优秀走向卓越。 ...
    编程 发布于2024-11-06
  • 在 React 中构建无限滚动组件
    在 React 中构建无限滚动组件
    介绍 我们在应用程序和网页中看到无限滚动,尤其是希望我们滚动的社交媒体。虽然无意识地滚动不好,但构建自己的无限滚动是很棒的。作为开发人员,我们应该尝试重新创建我们在网上冲浪时看到的组件。它可以挑战您在实现某些组件时了解更多信息并跳出框框进行思考。 此外,如果您希望在应用程序中实现无...
    编程 发布于2024-11-06
  • 在 React 中构建响应式会议图块的动态网格系统
    在 React 中构建响应式会议图块的动态网格系统
    In the era of remote work and virtual meetings, creating a responsive and dynamic grid system for displaying participant video tiles is crucial. Inspi...
    编程 发布于2024-11-06
  • 使用 Spring Boot 和 Spring Cloud 开发微服务
    使用 Spring Boot 和 Spring Cloud 开发微服务
    微服务架构已成为构建可扩展和模块化系统的流行解决方案。通过微服务,您可以将单一应用程序分解为更小的、独立的和专业的服务,这使得系统的维护和发展变得更加容易。在这篇文章中,我们将探讨如何使用 Spring Boot 和 Spring Cloud 创建健壮且高效的微服务。 微服务简介 微服务背后的主要思...
    编程 发布于2024-11-06
  • 克服 PHP DOM XML 解析中的挑战:问题和解决方案
    克服 PHP DOM XML 解析中的挑战:问题和解决方案
    简化 PHP DOM XML 解析:揭开要点当您浏览 PHP DOM 函数的复杂性时,可能会出现某些障碍。为了解决这些挑战,让我们开始了解 DOM 的复杂性,并找出常见问题的解决方案。问题 1:使用 xml:id 驯服 ID当使用 ID 来防止树中出现重复页面时,PHP 的 DOM 遇到了一个难题:...
    编程 发布于2024-11-06
  • 密码重置功能:使用 OTP 重置密码
    密码重置功能:使用 OTP 重置密码
    后端 2. 重置密码 转向下一个 API。 PUT 上 /api/reset-password, req -> otp, email, 新密码, res -> nocontent // controllers/passwordReset.go func ResetP...
    编程 发布于2024-11-06
  • 如何从全局站点包继承 Virtualenv 中的特定包?
    如何从全局站点包继承 Virtualenv 中的特定包?
    从全局站点包继承 Virtualenv 中的特定包为了增强虚拟环境 (virtualenv) 的功能,您可能希望从全局站点继承特定包站点包目录。这种方法允许您有选择地将重要的库合并到您的 virtualenv 中,而无需直接安装它们。继承方法要实现这种继承,请使用以下命令创建一个新的 virtual...
    编程 发布于2024-11-06
  • 如何解决 EF6 中的“找不到 'MySql.Data.MySqlClient\'\”错误?
    如何解决 EF6 中的“找不到 'MySql.Data.MySqlClient\'\”错误?
    MySQL 实体框架的提供程序注册使用 MySQL 和实体框架时,您可能会遇到错误“找不到 Entity Framework 提供程序” 'MySql.Data.MySqlClient' ADO.NET 提供程序。”尽管安装了最新的 MySQL 连接器,您可能仍然会遇到此问题。出现此...
    编程 发布于2024-11-06
  • 如何利用PHP防止邮件传输中的恶意输入?
    如何利用PHP防止邮件传输中的恶意输入?
    保护电子邮件传输的用户输入在 PHP 中,必须在发送电子邮件之前清理用户输入,以防止恶意或有害内容泄露你的系统。考虑下面的简单 PHP 邮件脚本的代码片段:<?php $to = "[email protected]"; $name = $_POST['name']; $m...
    编程 发布于2024-11-06
  • 应用页面开发
    应用页面开发
    Если посмотреть на исходный проект, то можно увидеть, что нам необходимо создать одну главную страницу. Результаты поиска авиабилетов, отелей и туров ...
    编程 发布于2024-11-06

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3