当我查看 Assert 类 JavaDoc 中的示例时
assertThat("Help! Integers don't work", 0, is(1)); // fails:
// failure message:
// Help! Integers don't work
// expected: is <1>
// got value: <0>
assertThat("Zero is one", 0, is(not(1))) // passes
我认为没有什么太大的优势,比如说,
assertEquals( 0, 1 )
。
如果结构变得更复杂,也许对消息来说很好,但是你看到更多优点了吗?可读性?
对于存在完全符合您意图的
assertFoo
的情况来说,没有太大优势。在这些情况下,它们的行为几乎相同。
但是当您进行更复杂的检查时,优势就变得更加明显:
val foo = List.of("someValue");
assertTrue(foo.contains("someValue") && foo.contains("anotherValue"));
Expected: is <true>
but: was <false>
与
val foo = List.of("someValue");
assertThat(foo, containsInAnyOrder("someValue", "anotherValue"));
Expected: iterable with items ["someValue", "anotherValue"] in any order
but: no item matches: "anotherValue" in ["someValue"]
人们可以讨论其中哪一个更容易阅读,但是一旦断言失败,您将从
assertThat
得到一条很好的错误消息,但从 assertTrue
只能得到非常少量的信息。
基本上是为了增加代码的可读性。
除了 hamcrest 之外,您还可以使用 fest 断言。 与 hamcrest 相比,它们具有一些优势,例如:
assertEquals(123, actual); // reads "assert equals 123 is actual"
vsassertThat(actual).isEqualTo(123); // reads "assert that actual is equal to 123")
import static org.fest.assertions.api.Assertions.*;
// common assertions
assertThat(yoda).isInstanceOf(Jedi.class);
assertThat(frodo.getName()).isEqualTo("Frodo");
assertThat(frodo).isNotEqualTo(sauron);
assertThat(frodo).isIn(fellowshipOfTheRing);
assertThat(sauron).isNotIn(fellowshipOfTheRing);
// String specific assertions
assertThat(frodo.getName()).startsWith("Fro").endsWith("do")
.isEqualToIgnoringCase("frodo");
// collection specific assertions
assertThat(fellowshipOfTheRing).hasSize(9)
.contains(frodo, sam)
.excludes(sauron);
// map specific assertions (One ring and elves ring bearers initialized before)
assertThat(ringBearers).hasSize(4)
.includes(entry(Ring.oneRing, frodo), entry(Ring.nenya, galadriel))
.excludes(entry(Ring.oneRing, aragorn));
Fest 不再活跃,请使用 AssertJ 代替。
一个非常基本的理由是很难弄乱新语法。
假设特定值 foo 在测试后应为 1。
assertEqual(1, foo);
--或--
assertThat(foo, is(1));
使用第一种方法,很容易忘记正确的顺序,然后倒着输入。然后,该消息不是说测试失败是因为它期望 1 而得到 2,而是相反。测试通过时不是问题,但测试失败时可能会导致混乱。
使用第二个版本,几乎不可能犯这个错误。
示例:
assertThat(5 , allOf(greaterThan(1),lessThan(3)));
// java.lang.AssertionError:
// Expected: (a value greater than <1> and a value less than <3>)
// got: <5>
assertTrue("Number not between 1 and 3!", 1 < 5 && 5 < 3);
// java.lang.AssertionError: Number not between 1 and 3!
btw:你也可以在assertXXX中写入文本...
assertThat(frodo.getName()).isEqualTo("Frodo");
接近自然语言。
更容易阅读,更容易分析代码。 程序员花在分析代码上的时间比编写新代码的时间多。因此,如果代码易于分析,那么开发人员的工作效率应该会更高。
附注 代码应该像写得好的书一样。 自记录代码。
assertThat 比assertEquals 有优势 -
1)更具可读性
2)有关失败的更多信息
3)编译时错误 - 而不是运行时错误
4)灵活编写测试条件
5) 可移植 - 如果您使用 hamcrest - 您可以使用 jUnit 或 TestNG 作为底层框架。