没有界面的伪造类

时间:2016-11-27 04:54:18

标签: java unit-testing

在单元测试时,我更喜欢使用伪类而不是模拟(更易读)。这在Python中很适合我,但在Java世界中,我通常需要为I类替换创建一个接口。这意味着我现在有3个:

而不是1个班级
  • 原班级
  • 界面
  • 用于测试的假冒版本

如果我想获得一个非常好的测试覆盖率,这实际上意味着我需要为我的项目中的每个类执行此操作,这是不可接受的。我只想为那些真正在生产代码中有多个实现的类创建一个接口。

我注意到Mockito允许您在不创建界面的情况下模拟具体类。我可以为假类使用这样的技巧吗?

例如,在测试注册系统时,会有一个电子邮件类。现在在测试中,我实际上并不想发送实际的电子邮件,所以我要么嘲笑这个类,要么假冒这个类。

class FakeEmailService {   
  public void sendEmail(String to, String body) {
    m_sent = true;
  }
}

现在我的注册系统构造函数接受原始类EmailService,但我想通过一些技巧在测试中使用FakeEmailService

Registration reg = new Registration(new FakeEmailService());

这在Python中很好,因为它不是静态类型的。

1 个答案:

答案 0 :(得分:1)

在java / jvm中,您至少有以下选项:

  1. 添加界面。如你所说,它增加了很多噪音
  2. 模拟课。这是最常见,最便宜,也可能是最有用的选项,如果你不喜欢这种语法,你可以创建自己的工厂
  3. 继承课程。当然只有'((1 4) (2 5) (3 6)) 不是最终的。但它不是一个好的解决方案,因为它很容易意外地将代码执行传递到原始类(通过构造函数而不是重写方法)并且在测试中有意外行为
  4. 使用任何其他允许鸭子打字的jvm语言。例如groovy非常受欢迎,很容易与java结合使用。它提供了轻松的嘲弄。使用spock框架,你将获得更强大的嘲弄。但是,imho,它比java更糟糕的重构支持。
  5. 我不知道有任何工具可以做到,但我可以想象,你需要的是使用一些高级代码处理(如lombok)和/或自定义类加载(如powermock)。我可以想象用它们来模拟java中的鸭子打字。但是,我还没有听说过像这样的工具