如何编写一个测试友好的不可变值类?

2024-04-14

我将不可变数据模型类标记为final确保更改其值的唯一方法是创建一个新实例。 (不幸的是,这些字段不能是最终的,因为它们需要由 Hibernate 填充。)

这工作得很好,直到我想检查另一个类在使用模型的无效实例调用时是否抛出正确的异常。模型的构造函数会验证参数,因此必须使用反射来设置字段。这是非常笨拙的,因为模型有相当多的字段,并且字段名称必须进行硬编码。

我也不能嘲笑该模型,因为它是最终的。 (是否应该使用接口来启用模拟,同时保持类不可变,是否也存在争议。通过使用接口,就无法以编程方式强制方法在实例的整个生命周期中必须返回相同的值。)

在这种情况下人们通常会做什么?有没有任何标准方法?


一般来说,您不应该想要模拟数据对象。数据对象应该没有逻辑,也没有外部依赖关系,因此模拟对象并没有多大用处。相反,可以非常轻松地创建假实例,您可以根据需要将其填充到方法中。

此外,还有一些其他原因您可能希望避免将 Hibernate 持久对象视为不可变:

  • Hibernate 提供的对象本质上是不是线程安全的 https://developer.atlassian.com/display/CONFDEV/Hibernate+Sessions+and+Transaction+Management+Guidelines#HibernateSessionsandTransactionManagementGuidelines-Multi-threading因此失去了不可变值对象通常提供的线程安全优势。
  • 你可能会发现你的对象实际上是proxies https://stackoverflow.com/questions/2594804/why-is-hibernate-returning-a-proxy-object,可能会削弱final语义。
  • Hibernate 控制的对象的操作方式完全不同他们的会议是否仍然开放 http://docs.jboss.org/hibernate/orm/3.6/javadocs/org/hibernate/Session.html(附加与分离)使它们成为不可变对象的非常糟糕的选择。如果您的不可变对象取决于会话生存期,那么它并不是真正不可变的。
  • 听起来有些对象在应用程序层可能有效或无效,超出了数据库层验证。这使得封装您的验证问题变得有点困难。
  • 您需要有一个公共的无参数构造函数,这与不可变值对象典型的实例控制类型相反。
  • 由于对象本质上是可变的,因此更复杂覆盖 equals 和 hashCode https://stackoverflow.com/a/1638886/1426891.

我的建议?如果您需要比 Hibernate DAO 所能提供的更多的不变性和数据验证保证,那么创建一个real具有最终字段(或私有构造函数和静态工厂方法)的最终不可变类,然后创建一个从 Hibernate DAO 复制值的构造函数(或静态工厂方法)。

如果您决定此选项,您将面临以下开销:two大致并行更改的数据对象,但您还可以获得分离关注点的好处(以防 Hibernate 对象出现分歧)以及真正不可变、等于和哈希码覆盖、会话不可知、保证有效的易用性您可以轻松创建用于测试的对象。

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

如何编写一个测试友好的不可变值类? 的相关文章

  • 同一服务器上的许多应用程序具有相同的 JMX Mbean 类

    我有超过 5 个 Spring Web 应用程序 它们都在使用另一个通用库 这个公共库有它自己的 MBean 由于强制的唯一 objectName 约束 我的应用程序无法部署在同一服务器上 我使用 MBean 的方式是这样的 Managed
  • “源兼容性”和“目标兼容性”有什么区别?

    之间有什么关系 区别sourceCompatibility and targetCompatibility 当它们设置为不同的值时会发生什么 根据工具链和兼容性 https docs gradle org current userguide
  • 连接外部 Accumulo 实例和 java

    我正在尝试使用 Accumulo 连接到虚拟机 问题是 我无法将其连接到 Java 中 我可以看到 Apache 抛出的网页 但我无法让它与代码一起工作 我认为这是缺乏知识的问题而不是真正的问题 但我找不到这方面的文档 所有示例都使用 lo
  • java程序有多少种结束方式?

    我知道使用 System exit 0 可以结束一个java程序 例如 如果我有一个JFrame窗口 它会关闭并结束程序 但我想知道还有多少其他方法 可以关闭它并结束程序 包括发生错误时 程序会被关闭 JFrame也会被关闭吗 添加到其他答
  • 非易失性领域的出版与阅读

    public class Factory private Singleton instance public Singleton getInstance Singleton res instance if res null synchron
  • 为什么在 10 个 Java 线程中递增一个数字不会得到 10 的值?

    我不明白 a 的值为0 为什么 a 不是10 那段代码的运行过程是怎样的 是否需要从Java内存模型来分析 这是我的测试代码 package com study concurrent demo import lombok extern sl
  • 查看Java Agent修改的Java类的源代码

    我需要了解 Java 代理如何修改我的初始类 以便我能够理解代码的作用 build gradle configurations jar archiveName agent2 jar jar manifest attributes Prema
  • 未装饰窗户的 Windows Snap 功能?

    有谁知道如何允许未装饰的窗户使用此功能 唯一的选择就是重新实施它 有任何想法吗 谢谢 可停靠可能是唯一的JToolBar http docs oracle com javase tutorial uiswing components too
  • 什么是 Android 测试协调器?

    谷歌最近发布了Android测试支持库1 0 读完后overview https android developers googleblog com 2017 07 android testing support library 10 is
  • JAXB - 忽略元素

    有什么方法可以忽略 Jaxb 解析中的元素吗 我有一个很大的 XML 文件 如果我可以忽略其中一个大而复杂的元素 那么它的解析速度可能会快很多 如果它根本无法验证元素内容并解析文档的其余部分 即使该元素不正确 那就更好了 例如 这应该只生成
  • 为什么在将 String 与 null 进行比较时会出现 NullPointerException?

    我的代码在以下行中出现空指针异常 if stringVariable equals null 在此语句之前 我声明了 stringVariable 并将其设置为数据库字段 在这个声明中 我试图检测该字段是否有null值 但不幸的是它坏了 有
  • 使用 JDBC 连接到 PostgreSql 的本地实例

    我在 Linux 机器上有一个正在运行的 PostgreSql 本地实例 当我使用psql来自 shell 的命令我成功登录 没有任何问题 我需要通过 JDBC 连接到 PostgreSql 但我不知道我到底应该传递什么url参数为Driv
  • UseCompressedOops JVM 标志有什么作用以及何时应该使用它?

    HotSpot JVM 标志是什么 XX UseCompressedOops我应该做什么以及什么时候使用它 在 64 位 Java 实例上使用它 与不使用它 时 我会看到什么样的性能和内存使用差异 去年大多数 HotSpot JVM 都默认
  • Android - 存储对ApplicationContext的引用

    我有一个静态 Preferences 类 其中包含一些应用程序首选项和类似的内容 可以在那里存储对 ApplicationContext 的引用吗 我需要该引用 以便我可以在不继承 Activity 的类中获取缓存文件夹和类似内容 你使用的
  • 按降序排序映射java8 [重复]

    这个问题在这里已经有答案了 private static
  • Tomcat 6 未从 WEB-INF/lib 加载 jar

    我正在尝试找出我的 tomcat 环境中的配置问题 我们的生产服务器正在运行 tomcat 安装并从共享 NFS 挂载读取战争 然而 当我尝试使用独立的盒子 及其配置 进行同样的战争时 我收到下面发布的错误 有趣的是 如果我将 WEB IN
  • java实现excel价格、收益率函数[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 检测到 JVM 正在关闭

    我有一个使用 addShutdownHook 处理 Ctrl C 的 Swing 应用程序 它工作正常 直到我的关闭任务之一调用一个在正常情况下更改 JLabel 文本的函数 此时它挂起 我认为问题是 Swing EDT 已终止或正在等待某
  • 如何让 Firebase 与 Java 后端配合使用

    首先 如果这个问题过于抽象或不适合本网站 我想表示歉意 我真的不知道还能去哪里问 目前我已经在 iOS 和 Android 上开发了应用程序 他们将所有状态保存在 Firebase 中 因此所有内容都会立即保存到 Firebase 实时数据
  • Java 的“&&”与“&”运算符

    我使用的示例来自 Java Herbert Schildt 的完整参考文献 第 12 版 Java 是 14 他给出了以下 2 个示例 如果阻止 第一个是好的 第二个是错误的 因此发表评论 public class PatternMatch

随机推荐