Java 为什么我应该使用 Hamcrest-Matcher 和 assertThat() 而不是传统的 assertXXX()-方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1701113/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why should I use Hamcrest-Matcher and assertThat() instead of traditional assertXXX()-Methods
提问by
When I look at the examples in the Assert class JavaDoc
当我查看 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
I dont see a big advantage over, let's say, assertEquals( 0, 1 )
.
我看不出有什么大的优势,比方说,assertEquals( 0, 1 )
。
It's nice maybe for the messages if the constructs get more complicated but do you see more advantages? Readability?
如果结构变得更复杂,那么消息可能会很好,但是您是否看到了更多优势?可读性?
回答by Joachim Sauer
There's no big advantage for those cases where an assertFoo
exists that exactly matches your intent. In those cases they behave almost the same.
对于那些assertFoo
与您的意图完全匹配的存在的情况,没有什么大的优势。在这些情况下,它们的行为几乎相同。
But when you come to checks that are somewhat more complex, then the advantage becomes more visible:
但是当您遇到更复杂的检查时,优势就会变得更加明显:
assertTrue(foo.contains("someValue") && foo.contains("anotherValue"));
vs.
对比
assertThat(foo, hasItems("someValue", "anotherValue"));
One can discuss which one of those is easier to read, but once the assert fails, you'll get a good error message from assertThat
, but only a very minimal amount of information from assertTrue
.
人们可以讨论其中哪一个更容易阅读,但是一旦断言失败,您将收到来自 的很好的错误消息assertThat
,但来自 的信息量非常少assertTrue
。
assertThat
will tell you what the assertion was and what you got instead. assertTrue
will only tell you that you got false
where you expected true
.
assertThat
会告诉你断言是什么以及你得到了什么。assertTrue
只会告诉你你到达了false
你期望的地方true
。
回答by Manur
The JUnit release notesfor version 4.4 (where it was introduced) state four advantages :
4.4 版的 JUnit发行说明(引入它的地方)陈述了四个优点:
- More readable and typeable: this syntax allows you to think in terms of subject, verb, object (assert "x is 3") rather than assertEquals, which uses verb, object, subject (assert "equals 3 x")
- Combinations: any matcher statement s can be negated (not(s)), combined (either(s).or(t)), mapped to a collection (each(s)), or used in custom combinations (afterFiveSeconds(s))
- Readable failure messages. (...)
- Custom Matchers. By implementing the Matcherinterface yourself, you can get all of the above benefits for your own custom assertions.
- 更具可读性和可键入性:此语法允许您根据主语、动词、宾语(断言“x 是 3”)而不是assertEquals进行思考,后者使用动词、宾语、主语(断言“等于 3 x”)
- 组合:任何匹配器语句 s 都可以否定(not(s))、组合(any(s).or(t))、映射到集合(each(s))或用于自定义组合(afterFiveSeconds(s))
- 可读的失败消息。(……)
- 自定义匹配器。通过自己实现Matcher接口,您可以为自己的自定义断言获得上述所有好处。
More detailed argumentation from the guy who created the new syntax : here.
来自创建新语法的人的更详细的论证:here。
回答by MartinL
Example:
例子:
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!
- you can make your tests more particular
- you get a more detailed Exception, if tests fail
- easier to read the Test
- 你可以让你的测试更具体
- 如果测试失败,您会得到更详细的异常
- 更容易阅读测试
btw: you can write Text in assertXXX too...
顺便说一句:您也可以在 assertXXX 中编写 Text ......
回答by Andy Davis
A very basic justification is that it is hard to mess up the new syntax.
一个非常基本的理由是很难弄乱新语法。
Suppose that a particular value, foo, should be 1 after a test.
假设某个特定值 foo 在测试后应为 1。
assertEqual(1, foo);
--OR--
- 或者 -
assertThat(foo, is(1));
With the first approach, it is very easy to forget the correct order, and type it backwards. Then rather than saying that the test failed because it expected 1 and got 2, the message is backwards. Not a problem when the test passes, but can lead to confusion when the test fails.
使用第一种方法,很容易忘记正确的顺序,然后倒过来输入。然后,与其说测试失败是因为它预期为 1 而得到 2,不如说是倒退。测试通过时不是问题,但当测试失败时可能会导致混乱。
With the second version, it is almost impossible to make this mistake.
使用第二个版本,几乎不可能犯这个错误。
回答by Igor Popov
Basically for increasing the readability of the code.
基本上是为了增加代码的可读性。
Besides hamcrest you can also use the fest assertions. They have a few advantages over hamcrestsuch as:
除了 hamcrest,您还可以使用fest assertions。与 hamcrest 相比,它们有一些优势,例如:
- they are more readable
(assertEquals(123, actual); // reads "assert equals 123 is actual"
vsassertThat(actual).isEqualTo(123); // reads "assert that actual is equal to 123")
- they are discoverable (you can make autocompletion work with any IDE).
- 它们更具可读性
(assertEquals(123, actual); // reads "assert equals 123 is actual"
vsassertThat(actual).isEqualTo(123); // reads "assert that actual is equal to 123")
- 它们是可发现的(您可以使用任何 IDE 进行自动完成)。
Some examples
一些例子
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));
October 17th, 2016 Update
2016 年 10 月 17 日更新
Fest is not active anymore, use AssertJinstead.
Fest 不再活跃,请改用AssertJ。
回答by user4515828
assertThat(frodo.getName()).isEqualTo("Frodo");
Is close to natural language.
接近自然语言。
Easier read, easier analyze code. Programer spend more time to analyze code than write new one. So if code will be easy to analyze then developer should be more productive.
更容易阅读,更容易分析代码。程序员花更多的时间来分析代码而不是编写新代码。因此,如果代码易于分析,那么开发人员应该更有效率。
P.S. Code should be as well-written book. Self documented code.
PS Code 应该是一本写得很好的书。自我记录的代码。
回答by samshers
there are advantages to assertThat over assertEquals -
1) more readable
2) more information on failure
3) compile time errors - rather than run time errors
4) flexibility with writing test conditions
5) portable - if you are using hamcrest - you can use jUnit or TestNG as the underlying framework.
与 assertEquals 相比,assertThat 有优势 -
1) 更具可读性
2) 有关失败的更多信息
3) 编译时错误 - 而不是运行时错误
4) 编写测试条件的灵活性
5) 可移植 - 如果您使用 hamcrest - 您可以使用 jUnit或 TestNG 作为底层框架。