【问题标题】:Mock direct instantiation of classes模拟类的直接实例化
【发布时间】:2015-07-20 10:06:32
【问题描述】:

我经常遇到模拟类直接实例化的问题:

final File configFile = new File(pathFile);

我想模拟 new File(pathFile) 以制作 doReturn(otherFile)

我发现我可以通过将其包装在另一种方法中来模拟直接实例化。问题是我不想修改我所有的代码,只为单元测试创​​建实例化方法,那会很丑。

还有其他方法吗?

【问题讨论】:

标签: java mocking mockito


【解决方案1】:

在理想情况下,您的方法调用是不透明的:您可以影响它的唯一方法是更改​​其状态、依赖项或参数。构造函数本质上是静态方法调用,它不会(在 Java 中)提供覆盖或调整行为的机会。构造函数也可能是内联的,并且在某些虚拟机上可能会发生。

除了为自己创建测试“接缝”(例如工厂对象或可覆盖方法)之外,您唯一的选择是在编译类和在测试中运行它之间编辑字节码——顺便说一下, 是what PowerMock does,在默认语言环境的评论中。尽管 PowerMock 是一个功能强大且有用的库,但它确实有一些非常具体的安装步骤,这些步骤可能很难正确完成,然后您正在测试被测类的 PowerMock 编辑版本,而不是类本身。

有关相关问题(如何在私有字段中模拟实例),请参阅 this answer。具体结果是不同的,但同样你必须重构测试或打破封装。

【讨论】:

  • 模拟或包装File 是个坏主意,尽管模拟File 实际上可以干净利落地完成。 “构造函数可以内联”对我来说毫无意义;它是否会发生是无关紧要的。 PowerMock 确实存在一些可用性问题,但你让它听起来比实际情况要糟糕得多; AFAIK,很多 Mockito 用户有时会使用它。关于“测试 PowerMock 编辑版本”的最后一点对我来说听起来不过是 FUD。我从经验中知道这不是一个真正的问题。
  • 很抱歉我的回答不适合你;我关于 PowerMock 的观点仅仅是“a good unit test should be as realistic as you can make it”,你在其他地方写的,除了一个“丑陋”的方法(来自问题)或一个调用的字节码级重写之外,没有很多机会否则将是静态且不可更改的(Powermock)。我不认为这些观点特别有争议。
  • 是的,我更喜欢 integration 测试(没有或最少模拟)而不是 unit 测试。所以,创建一个“接缝”嘲笑File在这里都是丑陋的;一个好的测试将使用真实文件。不过,偶尔需要模拟,然后你需要模拟的是static、构造函数等,这无关紧要;模拟工具应该完成所需的工作,而不会强制对被测代码进行妥协。一个真实的例子:我最近为一个 Java EE 7 Web 应用程序编写了集成测试,我需要在其中模拟 FacesContext.getCurrentInstance() 静态方法。
  • 我不是在提倡模拟文件; OP 想要替换一个不同的文件,这在测试中很常见,并且(对我而言)最好通过重构来实现灵活性(即引入接缝)。无论如何,PowerMock 是某些工作的正确工具,即使我自己不喜欢它——我在这里提到它只是为了解释它是如何工作的为了解释它对代码修改的深度模拟没有明确的接缝.
猜你喜欢
  • 2021-01-19
  • 2018-11-02
  • 2015-03-01
  • 1970-01-01
  • 2011-12-20
  • 1970-01-01
  • 1970-01-01
  • 2018-07-30
  • 1970-01-01
相关资源
最近更新 更多