将私有方法公开以对其进行单元测试...好主意吗?

2023-12-23

Moderator Note: There are already 39 answers posted here (some have been deleted). Before you post your answer, consider whether or not you can add something meaningful to the discussion. You're more than likely just repeating what someone else has already said.


我偶尔发现自己需要在类中公开一个私有方法,只是为了为其编写一些单元测试。

通常这是因为该方法包含类中其他方法之间共享的逻辑,并且单独测试逻辑会更整洁,或者可能的另一个原因是我想测试同步线程中使用的逻辑而不必担心线程问题。

其他人是否发现自己这样做,因为我真的不喜欢这样做?我个人认为,好处超过了将方法公开的问题,该方法实际上并没有在类之外提供任何服务......

UPDATE

感谢大家的回答,似乎激起了人们的兴趣。我认为普遍的共识是测试应该通过公共 API 进行,因为这是使用类的唯一方式,我确实同意这一点。我上面提到的几个我会这样做的案例是不常见的案例,我认为这样做的好处是值得的。

然而,我可以看到每个人都认为这永远不应该发生。当更多地考虑它时,我认为更改代码以适应测试是一个坏主意 - 毕竟我认为测试在某种程度上是一种支持工具,并且如果您愿意的话,更改系统以“支持支持工具”是公然的不好的做法。


Note:
这个答案最初是针对这个问题发布的单独的单元测试是否是通过 getter 公开私有实例变量的好理由? https://stackoverflow.com/q/31646092/2422776它被合并到这个中,所以它可能有点特定于那里提出的用例。

作为一般性声明,我通常赞成重构“生产”代码以使其更易于测试。然而,我认为这不是一个好的选择。一个好的单元测试(通常)不应该关心类的实现细节,而只关心它的可见行为。您可以测试该类在调用后是否按照您期望的顺序返回页面,而不是将内部堆栈暴露给测试first() or last().

例如,考虑这个伪代码:

public class NavigationTest {
    private Navigation nav;

    @Before
    public void setUp() {
        // Set up nav so the order is page1->page2->page3 and
        // we've moved back to page2
        nav = ...;
    }

    @Test
    public void testFirst() {
        nav.first();

        assertEquals("page1", nav.getPage());

        nav.next();
        assertEquals("page2", nav.getPage());

        nav.next();
        assertEquals("page3", nav.getPage());
    }

    @Test
    public void testLast() {
        nav.last();

        assertEquals("page3", nav.getPage());

        nav.previous();
        assertEquals("page2", nav.getPage());

        nav.previous();
        assertEquals("page1", nav.getPage());
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将私有方法公开以对其进行单元测试...好主意吗? 的相关文章

  • 方程“a + bx = c + dy”的积分解

    在等式中a bx c dy 所有变量都是整数 a b c and d是已知的 我如何找到整体解决方案x and y 如果我的想法是正确的 将会有无限多个解 由最小公倍数分隔b and d 但我只需要一个解决方案 我可以计算其余的 这是一个例
  • 为什么这个字符串用AesCryptoServiceProvider第二次解密时不相等?

    我在 C VS2012 NET 4 5 中的文本加密和解密方面遇到问题 具体来说 当我加密并随后解密字符串时 输出与输入不同 然而 奇怪的是 如果我复制加密的输出并将其硬编码为字符串文字 解密就会起作用 以下代码示例说明了该问题 我究竟做错
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • 测试弱引用

    在 Java 中测试弱引用的正确方法是什么 我最初的想法是执行以下操作 public class WeakReferenceTest public class Target private String value public Targe
  • 我可以创建自定义 java.* 包吗?

    我可以创建一个与预定义包同名的自己的包吗在Java中 比如java lang 如果是这样 结果会怎样 这难道不能让我访问该包的受保护的成员 如果不是 是什么阻止我这样做 No java lang被禁止 安全管理器不允许 自定义 类java
  • 游戏内的java.awt.Robot?

    我正在尝试使用下面的代码来模拟击键 当我打开记事本时 它工作正常 但当我打开我想使用它的游戏时 它没有执行任何操作 所以按键似乎不起作用 我尝试模拟鼠标移动和点击 这些动作确实有效 有谁知道如何解决这个问题 我发现这个问题 如何在游戏中使用
  • C# 动态/expando 对象的深度/嵌套/递归合并

    我需要在 C 中 合并 2 个动态对象 我在 stackexchange 上找到的所有内容仅涵盖非递归合并 但我正在寻找能够进行递归或深度合并的东西 非常类似于jQuery 的 extend obj1 obj2 http api jquer
  • 将 Azure AD 高级自定义角色与 Spring Security 结合使用以进行基于角色的访问

    我创建了一个演示 Spring Boot 应用程序 我想在其中使用 AD 身份验证和授权 并使用 AD 和 Spring Security 查看 Azure 文档 我执行了以下操作 package com myapp contactdb c
  • 编译时展开 for 循环内的模板参数?

    维基百科 here http en wikipedia org wiki Template metaprogramming Compile time code optimization 给出了 for 循环的编译时展开 我想知道我们是否可以
  • 在 WPF 中使用 ReactiveUI 提供长时间运行命令反馈的正确方法

    我有一个 C WPF NET 4 5 应用程序 用户将用它来打开某些文件 然后 应用程序将经历很多动作 读取文件 通过许多插件和解析器传递它 这些文件可能相当大 gt 100MB 因此这可能需要一段时间 我想让用户了解 UI 中发生的情况
  • C# 中的 IPC 机制 - 用法和最佳实践

    不久前我在 Win32 代码中使用了 IPC 临界区 事件和信号量 NET环境下场景如何 是否有任何教程解释所有可用选项以及何时使用以及为什么 微软最近在IPC方面的东西是Windows 通信基础 http en wikipedia org
  • javafx android 中的文本字段和组合框问题

    我在简单的 javafx android 应用程序中遇到问题 问题是我使用 gradle javafxmobile plugin 在 netbeans ide 中构建了非常简单的应用程序 其中包含一些文本字段和组合框 我在 android
  • 具有特定参数的 Spring AOP 切入点

    我需要创建一个我觉得很难描述的方面 所以让我指出一下想法 com x y 包 或任何子包 中的任何方法 一个方法参数是接口 javax portlet PortletRequest 的实现 该方法中可能有更多参数 它们可以是任何顺序 我需要
  • 对于某些 PDF 文件,LoadIFilter() 返回 -2147467259

    我正在尝试使用 Adob e IFilter 搜索 PDF 文件 我的代码是用 C 编写的 我使用 p invoke 来获取 IFilter 的实例 DllImport query dll SetLastError true CharSet
  • 为什么C++代码执行速度比java慢?

    我最近用 Java 编写了一个计算密集型算法 然后将其翻译为 C 令我惊讶的是 C 的执行速度要慢得多 我现在已经编写了一个更短的 Java 测试程序和一个相应的 C 程序 见下文 我的原始代码具有大量数组访问功能 测试代码也是如此 C 的
  • 如何使用 JSch 将多行命令输出存储到变量中

    所以 我有一段很好的代码 我很难理解 它允许我向我的服务器发送命令 并获得一行响应 该代码有效 但我想从服务器返回多行 主要类是 JSch jSch new JSch MyUserInfo ui new MyUserInfo String
  • 单元测试时 Android Studio 2.0 中测试状态终止且没有任何失败消息

    Issue 我昨天在 Ubuntu 上从 1 5 升级到了 Android Studio 2 0 当我在 Android Studio 2 0 中进行单元测试时 即使所有测试都已通过 它也会显示 终止测试 状态 有时它只显示部分测试通过 我
  • ServletContainer 类未找到异常

    我无法再编译我的球衣项目 并且出现以下异常 GRAVE Servlet Project API threw load exception java lang ClassNotFoundException com sun jersey spi
  • 如何确定 CultureInfo 实例是否支持拉丁字符

    是否可以确定是否CultureInfo http msdn microsoft com en us library system globalization cultureinfo aspx我正在使用的实例是否基于拉丁字符集 我相信你可以使
  • 使用 WGL 创建现代 OpenGL 上下文?

    我正在尝试使用 Windows 函数创建 OpenGL 上下文 现代版本 基本上代码就是 创建窗口类 注册班级 创建一个窗口 choose PIXELFORMATDESCRIPTOR并设置它 创建旧版 OpenGL 上下文 使上下文成为当前

随机推荐

  • VS Code 未显示有用的 Python 代码片段

    Visual Studio Code 不再显示 Python 代码片段 我不知道这是 Python Language Server 的 bug 我已经尝试过 Jedi Microsoft 和 Pylance 还是 VSCode 的问题 它用
  • Facebook Sharer 问题(每个单词后面总是显示 (+) 和 (%))

    我想问一下如何解决我的 Facebook 共享器问题 每当我想通过 Facebook 分享器分享我的文章时 它都会弹出 Facebook 窗口 这完全没问题 但在窗口中 每个单词后面都会显示加号 和 你们能帮我吗 您可以在我的网站上查看 h
  • Linq to SQL,基于 If/Else 具有不同返回类型的存储过程

    我有一个现有的存储过程 我现在尝试使用 LINQ to SQL 调用它 这是存储过程 ALTER procedure dbo sp SELECT Security ALL UID Varchar 15 as DECLARE A ID int
  • Analytics.js 的 SegmentIO 开源版本设置问题

    我正在从 SegmentIO 切换到他们的开源版本 我用过这个博客文章 http pivotallabs com how to use analytics js to fix your analytics code and achieve
  • Lightsail 中没有 Amazon Linux 2?

    尝试在 AWS Lightsail 上创建新实例时 只有适用于 AWS Linux 2018 03 0 的选项 而没有适用于 AWS Linux 2 的选项 鉴于 AWS Linux 将于 2020 年 12 月终止支持 我有点担心在 Li
  • 在 Docker 中运行 Jenkins - 立即退出

    我正在尝试使用 docker 运行 Jenkins 服务器 我已经构建了图像 并尝试使用以下命令运行它 docker run p 8080 8080 62a4e44bf4bf 62a4e44bf4bf 是 docker 镜像 ID 每当我运
  • SQL Server Reporting Services url 参数不起作用

    我无法正确地将参数传递到 SQL Server 报告服务器 显示报表页面 但报表查看器 Web 部件的参数提示仍然为空 并且没有运行任何内容 以下网址将我带到正确的报告页面 我可以在其中手动选择参数 然后单击 查看报告 按钮并获取报告 ht
  • localStorage 的设置值有副作用吗?

    我正在开发一个必须保存的 React Redux 应用程序certain值从商店到localStorage 我有一些实用功能 可以安全地将值存储到localStorage 我有一个动作 thunk 和减速器 const wallet sta
  • Express.js 项目中在哪里进行验证 – 数据库层验证(re. Mongoose)?

    我正在 Express js 中编写一个带有表单的应用程序 首先 我在路由 或控制器 如果您愿意的话 中进行所有验证 app post register function req res next Generic validation re
  • Cordova / Phonegap 所有外部 Ajax 请求返回 404

    我确实有一个 Cordova 3 3 应用程序 但昨天我将 cordova 和所有应用程序插件更新为 apache cordova v5 0 自从我这样做以来 我放置了一个闪屏插件并毫无问题地构建了我的应用程序 但是当我尝试测试时 我看到所
  • HTML5 Canvas 绘制像素的颜色与提供的颜色不同

    设置某种颜色后fillStyle画布并绘制一个矩形fillRect 矩形的颜色有时与提供的颜色略有不同 getImageData返回不同的值 通常其中一个值小 1 似乎只有在使用时才会发生rgba颜色 而不是与rgb 但我实际上确实需要使用
  • JBoss 5 上的 RESTEasy - 需要 jar

    我们正在运行 JBoss 5 1 0 我正在尝试使用 RESTEasy 启动并运行一个简单的测试应用程序 但是 我无法弄清楚我需要什么才能做到这一点 显然新版本的 JBoss 已经包含了所有内容 但这对我没有帮助 据我了解 我需要修改应用程
  • 如何使用宏将字符串转换为变量名?

    define TRACE arg1 char arg1 int main void int a 4 TRACE Hello a convert Hello to a valid char variable name return 0 我在转
  • BeautifulSoup:获取特定表的内容

    我当地的机场 http www iaa gov il Rashat he IL Airports BenGurion informationForTravelers OnlineFlights aspx flightsType arr可耻地
  • 重新编译 Heroku slug,无需推送或更改配置

    我想知道是否有一种方法可以强制 Heroku 重新编译 slug 而不需要推送新的提交和 或更新配置变量 我为什么要这样做 我在 Heroku 上使用 Cedar 堆栈作为 Rails 3 2 应用程序 但在使用时遇到问题rake asse
  • 加载 Keras 模型时未知的初始化程序:GlorotUniform

    我通过 google colab 训练了我的 CNN VGG 并生成了 h5 文件 现在的问题是 我可以通过 google colab 成功预测我的输出 但是当我下载 h5 训练模型文件并尝试在我的笔记本电脑上预测输出时 我在加载模型时遇到
  • 尽管安装成功但无法识别节点

    我试着跑nodejs在全新安装的Windows 7的 这就是我所做的 使用 Windows 安装程序安装节点 确保文件被提取到C Program Files x86 nodejs 确保我的 Path 环境变量包含C Program File
  • Apache C++ 模块持久全局对象

    我希望在 Apache C 模块中保持一些全局对象在 Apache 子进程调用中保持不变 我该怎么做呢 您必须使用 Apache 进程外部的某种形式的存储 基本选择 一个数据库 共享内存 取决于操作系统 另一个进程并使用IPC机制 例如套接
  • Google Calendar API - 只能更新事件一次

    我遇到了与这篇文章中描述的相同的问题 Google Calendar api v3 重新更新问题 https stackoverflow com questions 8574088 google calendar api v3 re upd
  • 将私有方法公开以对其进行单元测试...好主意吗?

    Moderator Note There are already 39 answers posted here some have been deleted Before you post your answer consider whet