Java 8:静态助手与常见测试断言的默认方法

时间:2015-04-12 22:00:23

标签: java unit-testing

我已经在很多项目中使用Java进行TDD,而且我总是要处理在某些测试之间分享一些常见断言的情况。我的Java 8之前的解决方案总是这样。

具有常见断言和静态方法的类:

class CommonAssertions {
  static void assertCorrectUser(User user) {
    // bunch of assertions
  }
}

像这样使用:

class FooTest {
  @Test
  void somethingToDoWithUser() {
    User user = // obtain user somehow
    CommonAssertions.assertCorrectUser(user);
  }
}

现在使用Java 8我很想使用带有default方法的接口来进行常见断言:

interface CommonAssertions {
  default assertCorrectUser(User user) {
    // bunch of assertions on user
  }
}

然后我不是静态调用而是设计我的测试:

class FooTest implements CommonAssertions { ... }

它非常相似,但似乎第二个更容易使用(节省了一堆静态导入)并且更多地展示了测试。图像代码如:

class CompanyResourceTest implements UserAssertions, CompanyAssertions, JsonErrorAssertions { ... }

有些人可能认为default是针对完全不同的东西设计的,这是一种误用。有些人可能会认为这与将一堆常量放入interface并实现它一样糟糕。但这种方法真的有缺点吗?

1 个答案:

答案 0 :(得分:0)

缺点是不清楚。接口是未指定实现细节的合同。通过使用所有默认方法,您可以滥用界面的设计,这通常会使代码更难理解。 Java在某种意义上是有限的,因为它不支持mixin或traits,并且使用默认接口只是一种愚蠢的方式。

静态方法是java中的常规方法,但如果您真的反对它们,我会提出几种选择:

  • 用支持mixins的语言编写测试,例如groovy 或者scala
  • 创建您的公共基础测试类,例如UserTest,并让您的用户相关测试扩展它。不理想,特别是如果你需要多重继承。
  • 编写可以在测试中注入这些方法的注释,这样你就可以拥有可以在这些方法中编译的@UserTest。