用类替换单身人士是否存在任何潜在问题?

时间:2017-06-14 19:06:32

标签: scala unit-testing testing mocking

我目前正在研究Scala项目,并且在测试广泛使用Singleton对象的代码时遇到了困难。

我有像这样的单身人士:

object SomeSingleton {
  def someFunction(s: String): String = s + "b"
}

在某个项目的某个地方,我将其用于我想测试的方法:

  val s = SomeSingleton.someFunction("a")

我开发了新功能,我希望SomeSingleton.someFunction在没有真正方法调用的情况下在测试中返回一些特定值,我在Java中使用Powermock做了这个,但我在Scala中找不到这样做的方法。 我知道如何仍然可以做到这一点,但它意味着将原始代码更改为:

object SomeSingleton extends SomeSingletonClass{}

class SomeSingletonClass {
  // Whole logic from SomeSingleton moves here
  def someFunction(s: String): String = s + "b"
}

现在,我可以将SomeSingleton的使用替换为SomeSingletonClass并正确模拟它。所以这是我的担忧,项目不小,它不是100%测试覆盖,我对Scala相对较新,所以我不确定,它会导致什么不良后果?这是一个可行的解决方案?由于这个原因,我不希望遗留代码在某个随机位置中断。

1 个答案:

答案 0 :(得分:1)

鉴于你拥有的(遗留代码有很多单身人士),我认为你的解决方案可能还可以。我想在这里分享我的一些想法。

  1. 是的,介绍SomeSingletonClass课程将有助于嘲笑课程,但缺点是它不再是单身人士。我可以很容易地做val newSingleton = new SomeSingletonClass(),瞧,我已经创建了一个新对象。测试单例的最好方法是,直接测试单例。我猜你的单身人士会调用更多其他单身人士,而你并不想执行所有这些副作用。但要正确解决问题,您需要对代码进行广泛的重构。

  2. PowerMock是Java中非常强大的模拟工具(可能功能太大)。它可以模拟静态方法/单例的方法是修改字节代码。它适用于大多数情况,但是当它没有时,你完全不知道如何解决它。在我之前在亚马逊的工作中,我们曾经广泛使用过PowerMock,但是由于它的黑盒魔术,我们慢慢地远离它。帮助我们实现这一目标的一种方法是使用依赖注入,您可以轻松地在测试中注入模拟对象。

  3. 我可以看到您正在处理遗留代码,因此重写所有内容并不容易(例如,引入依赖注入,甚至是新的SomeSingletonClass。在这里尝试)。我的建议是,您可能不应该花太多时间为遗留代码编写测试。相反,在编写新代码时,请尝试使其可测试,并根据需要重构遗留代码。