【问题标题】:How do I mock a class marked final and has a private constructor using jMockit如何使用 jMockit 模拟标记为 final 的类并具有私有构造函数
【发布时间】:2015-02-04 08:53:51
【问题描述】:

我想使用JMockit 编写一些基于状态的测试来模拟CSVRecord。问题是CSVRecord 是final(这意味着我必须使用像JMockit 这样的模拟框架)并且CSVRecord's 构造函数具有包私有可见性。

由于它是包私有的,我不能调用 new CSVRecord(arg, arg, ...),这意味着我永远无法实例化我的模拟。 它的父类 CSVParser 是唯一可以创建实例的类。

JMockit 有办法处理这种情况吗?

注意:JMockit 或 Mockito 是我们在此项目中使用的唯一框架。没有其他框架是可以接受的。我的偏好是使用 MockUp。

【问题讨论】:

    标签: java unit-testing jmockit


    【解决方案1】:

    用途:

    ConstructorReflection.newInstance

    在较新版本的 Jmockit 中。

    【讨论】:

    • 你忘了提到 ConstructorReflection 是一个 internal 类(因此不是 JMockit 发布的 API 的一部分),因此用户代码不应该使用它在未来的版本中可能会更改甚至删除。顺便说一句,这个问题的唯一好答案是我在答案的第一段中写的:not mock CSVRecord,这是一个糟糕的主意,因为它只是 CSVParser 的实现细节。
    • 内部类通常不会被标记为“公共”,除非开发人员在他们的 OO 技能上有点落后。 github.com/jmockit/jmockit1/blob/master/main/src/mockit/…
    • 什么?抱歉,但你不知道你在说什么......使用“内部”包(包含公共类,当然)是 Java 语言中的标准约定,因为它没有在 Java 9 之前不支持模块。例如,Eclipse 项目使用此约定。
    • 如果您提供另一个选项或答案会很有帮助,因为拒绝一些可以正常工作的东西是没有帮助的。
    【解决方案2】:

    听起来CSVRecord 不是一个很好的模拟对象。如果可能,最好针对另一个在内部使用它的公共类进行测试。

    否则,JMockit 会提供带有 newInstance 方法的 Deencapsulation 类。

    附带说明,Mockito 仅支持基于行为的测试; JMockit 提供了“mock-ups”(MockUp),但它与编写纯基于状态的黑盒测试不同。

    【讨论】:

    • 谢谢。是否可以使用 Deencapsulation.newInstance 显示解决方案以获取对 CSVRecord 的引用?
    • 只需调用它传递CSVRecord.class 作为第一个参数,然后是CSVRecord 中所需的构造函数具有的任何其他参数。
    • 不推荐使用的答案,因为 Deencapsulation 没有 newInstance 方法。
    【解决方案3】:

    如果只是调用私有构造函数的问题,那么是的,JMockit 有工具来处理它。见tutorial

    【讨论】:

    • 旧链接失效。非常无益的答案,因为它基本上说要查看巨大的 Jmockit 文档。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-13
    • 2013-09-03
    • 1970-01-01
    • 2011-06-01
    • 1970-01-01
    相关资源
    最近更新 更多