Java8:常见测试断言的静态帮助程序与默认方法
我已经在相当多的项目中使用Java进行了TDD,我总是要处理在某些测试之间共享一些常见断言的情况。我的前Java8解决方案总是这样 具有公共断言和静态方法的类:Java8:常见测试断言的静态帮助程序与默认方法,java,unit-testing,Java,Unit Testing,我已经在相当多的项目中使用Java进行了TDD,我总是要处理在某些测试之间共享一些常见断言的情况。我的前Java8解决方案总是这样 具有公共断言和静态方法的类: class CommonAssertions { static void assertCorrectUser(User user) { // bunch of assertions } } 这样使用: class FooTest { @Test void somethingToDoWithUser() {
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 { ... }
这很相似,但第二个似乎更易于使用(节省了大量静态导入),并揭示了更多关于测试的信息。图像代码如下:
类CompanyResourceTest实现用户断言、CompanyAssertions、JsonErrorAssertions{…}
有些人可能会争辩说,
default
是为完全不同的东西设计的,这是一种误用。有些人可能会说,这和将一堆常量放入接口中并实现它一样糟糕。但是这种方法真的有缺点吗 缺点是不清楚。接口是未指定实现细节的合同。通过使用所有默认方法,您滥用了接口的设计目的,这通常会使代码更难被其他人理解。Java是有限的,因为它不支持mixin或traits,而使用默认接口只是一种简单的方法
在java中,静态方法是这方面的标准,但如果您真的反对,我建议您使用以下几种替代方法:
- 使用支持混合的语言编写测试,例如groovy
还是斯卡拉
- 创建一个通用的基本测试类,比如UserTest,并让与用户相关的测试扩展它。不太理想,尤其是当您需要多重继承时
- 编写可以在测试中注入这些方法的注释,这样就可以在这些方法中编译@UserTest
这是上的一个变体。不惜一切代价避免它。default
方法应该是属于接口
的东西的合理的默认实现。使用static
实用程序方法和import static
删除类名。如果不想冗长,只需静态导入方法即可。