【问题标题】:How to mock a function used in the object constructor (with Mockito)?如何模拟对象构造函数中使用的函数(使用 Mockito)?
【发布时间】:2013-08-13 13:38:27
【问题描述】:

我需要使用 Java 为 Android 应用程序编写单元测试。我目前需要做的是创建一个对象 Picture 并将其用于一些测试。这个对象的问题是,它的构造函数有一个方法调用:

public Picture(File imageFile) {
    this.filename = imageFile.getName();
    this.imageDimension = getImageDimension();
    /.../
}

方法 getImageDimension() 引用了其他一些类,因此我更喜欢可分离性来模拟它的结果。对于模拟,我需要给 Mockito 一个构造函数,所以在我看来这就像一个鸡蛋问题。

那么,有没有机会用 Mockito 模拟对象构造函数中使用的函数?如果不是,不修改原代码如何解决这种情况?

【问题讨论】:

  • Picture 类如何获取“其他一些类”的实例。看起来那些是你想要注入模拟的那些。
  • @bowmore 它调用具有私有静态构造函数的 Android 框架 MainActivity 类。据我所知,从普通的 TestCase 类中模拟它是很棘手的。
  • 你不能把它隐藏在接口后面,并依赖接口来模拟它吗?
  • @bowmore 嗯,有可能,但我不确定(MainActivity是Android世界的必修神(类))。如果我能做到,那将意味着更改原始代码,如果我决定更改代码,我可以改为向 Picture 类添加一个用于测试的额外构造函数。我希望有一种神奇的技术,这样我就可以保持原始代码不变......

标签: java junit mockito


【解决方案1】:

通常你会模拟整个对象,而不仅仅是它的一部分。但如果它不是最终的,请创建一个 Picture 的子类并覆盖构造函数并在那里执行您的自定义操作。这样您就可以避免调用原始构造函数,并且可以测试实例。

如果它是最终的,那么单元测试就会变得非常困难。如果您实际上并未对这个特定类进行单元测试,则应该完全模拟图片对象或根本不模拟。

顺便说一句,这就是为什么你不应该让你的构造函数工作:它会导致代码难以测试和模拟。将对象初始化与逻辑分开是一件好事。可能您在这里想要的是一个额外的构造函数,它将文件名和维度作为构造函数参数。

【讨论】:

  • 感谢您的回复。 :) 我尝试模拟整个对象(成功),并注意到我错误地预期 Mockito 在到达构造函数中的方法时会崩溃(不知何故,我认为它无法成功模拟进一步的引用)。于是问题就解决了。但是,图片类是最终的,因此我不能用 Mockito 模拟对象,也不能子类化它。我想我会添加一个额外的构造函数并创建真实的对象。 PS - 被测试的代码不是我的创造......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-30
  • 1970-01-01
相关资源
最近更新 更多