不要模拟值对象:过于通用的规则,没有解释

2024-06-19

以下是 Mockito 单元测试框架的引用:

不要模拟值对象

为什么有人会想要这样做呢?

因为实例化对象太痛苦了!? => 无效 原因。如果创造新的装置太困难,那就是一个迹象 代码可能需要一些认真的重构。另一种方法是创建 价值对象的构建者——有一些工具可以实现这一点,包括 IDE 插件、Lombok 等。一个人也可以创造出有意义的东西 测试类路径中的工厂方法。

还有另一句话来自here http://www.mockobjects.com/2007/04/test-smell-everything-is-mocked.html:

为简单的值对象编写模拟没有多大意义 (无论如何应该是不可变的),只需创建一个实例并使用 它。不值得创建一个接口/实现对来控制返回哪些时间值,只需创建具有适当值的实例并使用它们即可。当一个类不值得嘲笑时,有一些启发式的方法。首先,它只有访问器或简单的方法来作用于它所持有的值,它没有任何有趣的行为。其次,除了 VideoImpl 或某些此类模糊术语之外,您无法为该类想出任何有意义的名称。

这似乎是哑值对象仅保存值而没有其他内容的合理原因,但是当您有一个引用实体和其他值对象的 ValueObject 时,事情会变得更加复杂。

假设我有 Person 和 Pet 对象,它们是实体,而 Relationship(所有者、医生等)是两个人之间的 ValueObject,并且有一个 ReasoningType,它也是一个 Value 对象。所以,关系基本上是:

class Relationship {
    private Person person;
    private Pet pet;
    private RelationshipType type;
}

现在,假设我有一个带有 isOwnerRelationship、isDoctorRelationship 等谓词的类。基本上谓词很简单

关系->关系.isOwner(); //委托关系Type.isOwner()

现在,我想测试谓词,我有两个选择:

模拟关系

public void testIsOwner() {
   Relationship rel = mock(Relationship.class);
   when(rel.isOwner()).thenReturn(true);

   assertTrue(RelationshipPredicates.isOwner(rel));
}

不要嘲笑关系

public void testIsOwner() {
   Person person = PersonBuilder.newPerson();
   Pet pet = PetBuilder.newDogPet();
   RelationshipType type = RelationshipTypes.ownerType();

   Relationship rel = new Relationship(person, pet, type);

   assertTrue(RelationshipPredicates.isOwner(rel));
}

当然,这个例子过于简化,因为对于一个人,你可能需要提供地址,对于宠物,你可能必须提供 BreedType,无论如何,即你可能需要提供的实体和值对象的传递图可能非常巨大。当然,您可以模拟实体,但假设您在关系内部有更多 ValueObjects 的 ValueObjects。即使您有出色的构建器,您也必须提供原始 ValueObject 的每个部分,即使单元测试仅测试它的单个方面。

在谓词测试中,如果谓词关心调用对象的一个​​特定方法或它们的组合,为什么我应该关心完整的对象构造?

或者是这样的值对象不能被视为simple并且规则不适用?


单元测试应该测试各个单元。所以,如果你的ValueObject足够简单,那么它不应该影响SUT(被测对象)的测试。然而,如果ValueObject有复杂的行为那么你应该嘲笑它。这简化了测试并仅对 SUT 进行隔离测试。

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

不要模拟值对象:过于通用的规则,没有解释 的相关文章

  • 在 Java 代码中存储加密密钥? [复制]

    这个问题在这里已经有答案了 我正在使用 JASYPT 在我们基于 Java 的软件中对密码进行加密解密 这就是我们加密密码的方法 StrongTextEncryptor textEncryptor new StrongTextEncrypt
  • 如何测试两个 Joda-Time DateTime 对象几乎相等?

    在单元测试中 我经常使用返回DateTime于或关于now 有没有办法说actual日期时间在几秒之内actual约会时间 这听起来是个坏主意 单元测试不应该以任何方式依赖于当前的实际时间 这就是为什么注入一些接口是一个很好的做法 称为Cl
  • Arrays.copyOf 产生浅拷贝还是深拷贝?

    对于是否应该这样做 似乎存在很多困惑和不同的意见 1 和其他来源 Arrays copyOf将产生深拷贝或浅拷贝 此测试表明副本很深 String sourceArray new String Foo String targetArray
  • 如何使用 selenium 和 junit 测试多个浏览器(版本)

    我刚刚发现了硒 一个很棒的工具 我计划运行 使用 selenium ide 生成的 junit4 代码 但我需要它与许多浏览器 网络驱动程序一起运行 这个用例有 junit java 模式吗 我的第一个想法是使用 RunWith Param
  • Java 中的双精度小数格式

    我在格式化双精度数的小数时遇到一些问题 如果我有双重值 例如4 0 如何格式化小数 使其变为 4 00 其中一种方法是使用数字格式 http docs oracle com javase tutorial i18n format decim
  • Java:输入/使用“try-catch”块的开销?

    这个问题说明了一切 尽管命中率不是很高 我测得速度慢了 1 5 倍到 2 倍 但使用 try catch 的字节码和不使用 try catch 的字节码之间没有区别 那么是什么让它通常变慢呢 PL 请注意 问题不是抛出异常的开销 而是进入
  • 在 IntelliJ IDEA 中编辑并继续?

    使用 IntelliJ IDEA 社区版进行调试时是否可以编辑一些代码 我在选项中找不到这个功能 是的 这就是所谓的 热插拔 您可以在调试过程中编译修改后的代码 并且类文件将被替换 直到您停止调试 确保在调试器设置中启用 HotSwap 选
  • Jest/Typescript:Jest 和 Typescript 中的模拟类依赖项

    我有依赖于类 A 的类 B 我想测试类 B 的方法 该方法在内部调用类 A 的方法 现在 我想通过模拟类 A 对类 B 的方法进行单元测试 我的代码结构 class A getSomething return Something class
  • Jackson - 将值传递给 JsonDeserializer

    我有一个现有的类层次结构 如下所示 public interface Service String getId String getName public class FooTask extends AbstractTask private
  • Java.lang.NoClassDefFoundError:com/fasterxml/jackson/databind/exc/InvalidDefinitionException

    我已经更新了我的依赖项 就像您在评论中所说的那样 我现在有这个 org springframework context ApplicationContextException Unable to start embedded contain
  • 预期在模拟中调用一次,但使用 Moq 时调用次数为 0 次

    我收到错误 在mock上调用一次 但是0次 下面是我的代码结构 public class GenerateAddress IGenerateAddress public GenerateAddress IAddress createAdd
  • 使用 rhino 模拟进行 lambda 单元测试失败

    如果我有这个测试 Expect Call session Single
  • 全屏 Swing 组件无法在 Mac OS X Mountain Lion 上的 Java 7 上接收键盘输入

    12 21 更新 7u10 最近发布 确认 问题仍然存在 值得庆幸的是 解决方法仍然有效 11 7 更新 我们有一个解决方法 来自 Oracle 的 Leonid Romanov 在 openjdk java net 邮件列表上提供了一些关
  • Android Widget 实现

    嗨 如果这个问题很愚蠢 我提前道歉 我对 Android 编程相当陌生 而且学得很快 我刚刚创建了一个任务提醒应用程序 并且想将该应用程序转换 实现为一个可以在主屏幕上查看的小部件 有什么方法吗 这可能吗 Thanks 如果没有更多关于您的
  • 从 java 反射中隐藏我的安全密钥

    下面的类是我用于加密的安全密钥提供程序 public class MySecretKey private String key 2sfdsdf7787fgrtdfg cj5 Some Util methods goes on Here 首先
  • 从 blob 反序列化 java 对象

    首先 我很抱歉 我要问一些愚蠢的问题 我根本不懂java 也不知道我们是否可以问这样的问题 如果没有 删除我的主题 oracle中有一个存储blob的表 它是二进制的 我能够解码它 输出看起来像这样 sr com epam insure c
  • java 未知深度的嵌套哈希图

    我有一个要求 我需要有一个嵌套的哈希图 但深度将在运行时决定 例如 如果在运行时 用户说 3 那么我的哈希图应该是这样的 HashMap
  • 将 JVM 参数放入要在运行时获取的文件中

    我正在构建当前应用程序的 jar 它需要设置几个 JVM 参数 有没有办法在文件中而不是在命令行上设置这些 JVM 参数 我已经做了一些搜索 看起来我可以使用 java properties 文件做一些事情 可能通过设置 java args
  • JSON 解析为 Java - Android 应用程序

    我需要在 Java Android 应用程序中解析 json 字符串的帮助 JSON 文件的文本 data columns location id name description latitude longitude error type
  • 客户端和服务器之间的安全连接

    我正在开发一个服务器组件 它将为嵌入式客户端的请求提供服务 这也在我的控制之下 现在一切都是测试版 安全性是这样的 客户端通过 https 发送用户名 密码 服务器返回访问令牌 客户端使用自定义标头中的访问令牌通过 http 发出进一步请求

随机推荐

  • Android Realm.io:行/对象不再有效

    这是我的删除功能 它确实找到了workday1 object public static void delete Context context Workday workday Realm realm getRealm context re
  • 使用不带参数的 Split() 时,默认分隔符是什么?

    所以我看了看String Split 今天 C 中的方法 我意识到你也可以向它传递零参数 这是我从未考虑过的 使用时默认的分隔符是什么Split 没有任何参数 如果没有值 则为空白 来源自here https msdn microsoft
  • NSCalendar 返回明年第一周上周一的错误日期

    我使用下面的代码使用随机日期来计算上周一 哪个工作文件但我的代码在明年日期中断 下面是相同的代码 NSDate date NSDate dateWithTimeIntervalSince1970 1483620311 228 NSLog c
  • MATLAB:在不使用循环的情况下提取矩阵的多个部分

    我有一个巨大的 2D 矩阵 我想从中提取 15 个不同的 100x100 部分 我有两个向量 x 和 y 其中保存了零件的左上角索引 我用过这样的东西 result cam1 x 1 end x 1 end 99 y 1 end y 1 e
  • 添加边后更新最大流量

    考虑我们有一个网络流量 并使用 Edmond Karp 算法 我们已经拥有网络上的最大流量 现在 如果我们向网络添加任意边 具有一定容量 更新最大流量的最佳方法是什么 我正在考虑更新关于新边缘的残差网络 并再次寻找增强路径 直到找到新的最大
  • Python在没有pandas的情况下解码excel表

    我正在尝试在 python 中读取 excel 文件而不使用pandas or xlrd 我一直在尝试将结果转换为bytes to utf 8没有任何成功 xls 文件中的数据 colA colB colC spc 1D0 20190705
  • 终端关闭时 bash 收到的信号

    使用 trap 来捕获信号 如下所示 i 1 while i lt 33 do trap echo i gt gt log txt i done 并强行关闭终端 那么log txt中的内容就是 redhat linux下 1 18 1 17
  • Java元数据读写

    是否可以以通用方式 对于所有图像类型 在 Java 中读取和写入元数据 我找到了一些示例 但它们总是特定的 例如 JPEG 或 PNG 我需要一些足够通用的东西 而不是到处都有 if else 语句 我不想重写源代码 但这是一个很好的例子
  • vscode 中正则表达式的不完整量词

    我正在尝试为对象的开头创建一个正则表达式 以便我可以用单个替换完整的块 在vscode的查找和替换中 My Regex id oid 0 9 product id 0 9 我的示例输入 id oid 973 product id 973 p
  • Typescript:如何在自定义过滤器中使用角度 $filter

    如何在自定义过滤器中使用 Angular filter 如何注入 filter依赖 module Filters export class CustomFilter public static Factory return function
  • Flask-Login 支持角色吗?

    如果没有 是否有任何项目在 Flask Login 中添加了此功能 否则 从 Flask Login 迁移到 Flask User 似乎有点令人畏惧 否则 是否有任何从 Flask Login 迁移到 Flask User 的方向 再次 为
  • Android系统每个应用程序的通知限制

    这可能偏离主题 但我找不到任何相关内容 Android应用程序可以显示的通知数量有限制吗 我在收到 100 条通知后遇到问题 没有文件明确说明这一点 注意 显示 100 条通知并不是一个好主意 但由于某些原因这是必需的 In API23 包
  • 无法验证包:721772200.itmsp

    我写这篇文章是因为我有一个严重的问题 我在cartoonsmart 网站上购买了Commander Cool 游戏 然而 一个严重的问题发生了 iTune Connect 验证无法接受该申请 我尝试从两个不同的开发者帐户发布它 但错误仍然发
  • Laravel nova diffForHumans 日期时间

    我对用户有字段last active 我想用 diffForHumans 或显示时间time from now来自 Moment js 我怎样才能做到呢 现在我只使用 DateTime make Activiy last active gt
  • 在 JavaScript 中定位提示弹出窗口

    我有一个如下所示的 JavaScript 提示 我想将提示放在屏幕中心 如何使用 javascript 做到这一点 function showUpdate var x var name prompt Please enter your na
  • 如何在 PHP 中使用 file_get_contents 获取图像的 MIME 类型

    我需要获取图像的 MIME 类型 但我只有图像的正文file get contents 是否有可能获取 MIME 类型 是的 你可以这样得到它 file info new finfo FILEINFO MIME TYPE mime type
  • SimpleDateFormat 将 lenient 设置为 false 时出现异常

    为什么这段代码会抛出无法解析日期的异常 SimpleDateFormat f new SimpleDateFormat yyyy MM dd T HH mm ss 000Z f setLenient false String dateStr
  • 为什么派生类不使用基类的operator=(赋值运算符)?

    以下是实际问题的简化版本 而不是打电话Base operator int 代码似乎生成了一个临时的Derived对象并复制它 既然函数签名似乎完美匹配 为什么不使用基本赋值运算符 这个简化的示例没有显示任何不良影响 但原始代码在析构函数中有
  • 在 IE10 中禁用捏合放大

    在 IE10 触摸模式下 我希望仅使页面的特定部分可缩放 其余的不应该 我找到了这个 http msdn microsoft com en US library ie hh772044 aspx http msdn microsoft co
  • 不要模拟值对象:过于通用的规则,没有解释

    以下是 Mockito 单元测试框架的引用 不要模拟值对象 为什么有人会想要这样做呢 因为实例化对象太痛苦了 gt 无效 原因 如果创造新的装置太困难 那就是一个迹象 代码可能需要一些认真的重构 另一种方法是创建 价值对象的构建者 有一些工