为什么JUnit在Java中断言方法不通用?

时间:2016-08-05 10:33:44

标签: java generics junit

我正在使用JUnit 4.12。断言方法本质上不是通用的。例如,assertEquals方法如下所示:

static public void assertEquals(Object expected, Object actual) {..}

为什么不喜欢?

static public <T> void assertEquals(T expected, T actual) {..}

我觉得需要通用方法声明来更好地进行编译时检查和IDE自动完成。

2 个答案:

答案 0 :(得分:5)

使用这样的通用方法:

<T> void assertEquals(T expected, T actual) { /* ... */ }

为了避免比较不同类型而没有类型安全性:您可以将任何内容传递给此方法,因为T退化为其上限Object

assertEquals("string", 0);  // Compiles fine, even though they can't be equal.

Ideone demo

您也无法使用expected上找不到的actualObject上的任何方法。因此,T基本上只是Object

因此,添加泛型只会使实现过于复杂。

现在,你可以定义一个这样的类:

class GenericAssert<T> {
  void assertEquals(T expected, T actual) { /* ... */ }
}

你可以这样使用:

new GenericAssert<String>().assertEquals("string", 0);  // Compiler error.

因为您现在已经在课程级别对assertEquals的可接受参数设置了更严格的上限。

但这只是感觉有点尴尬。

答案 1 :(得分:2)

你想看assertThat和Hamcrest匹配者; as assertThat实际上适用于泛型:

db.SaveChanges()

所以:

assertThat(String reason, T actual, Matcher<? super T> matcher) 

编译,但失败;而

assertEquals("abc", 123); 

甚至不会编译!

我甚至没有提到asser这个电话要好得多;当失败时提供更好的信息。您甚至可以使用它们来比较地图,集合等等。

长话短说:只有一个断言,任何人都需要 - 断言就是这样!