Почему я должен использовать Hamcrest-Matcher и assertThat () вместо традиционного assertXXX () - Методы - PullRequest
148 голосов
/ 09 ноября 2009

Когда я смотрю на примеры в классе 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 ).

Это может быть хорошо для сообщений, если конструкции усложняются, но вы видите больше преимуществ? Читаемость

Ответы [ 7 ]

167 голосов
/ 09 ноября 2009

Нет большого преимущества для тех случаев, когда существует assertFoo, который точно соответствует вашим намерениям. В этих случаях они ведут себя почти одинаково.

Но когда вы приходите к более сложным проверкам, преимущество становится более заметным:

assertTrue(foo.contains("someValue") && foo.contains("anotherValue"));

против

assertThat(foo, hasItems("someValue", "anotherValue"));

Можно обсудить, какой из них легче читать, но как только произойдет сбой утверждения, вы получите хорошее сообщение об ошибке от assertThat, но только очень небольшое количество информации от assertTrue.

assertThat расскажет вам, что было утверждение и что вы получили вместо этого. assertTrue только скажет вам, что вы получили false, где вы ожидали true.

45 голосов
/ 06 апреля 2010

Замечания к выпуску JUnit для версии 4.4 (где она была представлена) указывают на четыре преимущества:

  • Более читаемый и типизируемый: этот синтаксис позволяет вам мыслить с точки зрения субъекта, глагола, объекта (утверждают "x is 3"), а не assertEquals , который использует глагол, объект, субъект (assert " равно 3 х ")
  • Комбинации: любые операторы сопоставления s могут быть отменены ( not (s) ), объединены ( any (s). Or (t) ), сопоставлены с коллекцией ( каждый (ы) ) или используется в пользовательских комбинациях ( afterFiveSeconds (s) )
  • Читаемые сообщения об ошибках. (...)
  • Пользовательские совпадения. Реализовав интерфейс Matcher самостоятельно, вы можете получить все перечисленные выше преимущества для своих собственных утверждений.

Более подробная аргументация от парня, который создал новый синтаксис: здесь .

38 голосов
/ 14 октября 2012

В основном для увеличение читабельности кода .

Кроме подколенного сухожилия, вы также можете использовать утверждения фестиваля . Они имеют несколько преимуществ по сравнению с подголовником , таких как:

Некоторые примеры

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));

17 октября 2016 г. Обновление

Fest больше не активен, вместо этого используйте AssertJ .

18 голосов
/ 28 февраля 2012

Очень простое оправдание заключается в том, что сложно испортить новый синтаксис.

Предположим, что определенное значение foo должно быть 1 после теста.

assertEqual(1, foo);

- ИЛИ -

assertThat(foo, is(1));

При первом подходе очень легко забыть правильный порядок и набрать его задом наперед. Тогда вместо того, чтобы сказать, что тест не пройден, потому что он ожидал 1 и получил 2, сообщение возвращается. Не проблема при прохождении теста, но может привести к путанице, если тест не пройден.

Со второй версией почти невозможно совершить эту ошибку.

9 голосов
/ 31 октября 2011

Пример:

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!
  1. Вы можете сделать свои тесты более точными
  2. вы получите более подробное исключение, если тесты не пройдены
  3. легче читать тест

Кстати: вы также можете написать текст в assertXXX ...

3 голосов
/ 01 февраля 2015
assertThat(frodo.getName()).isEqualTo("Frodo");

Близок к естественному языку.

Легче читать, легче анализировать код. Программист тратит больше времени на анализ кода, чем на написание нового. Поэтому, если код будет легко анализировать, разработчик должен быть более продуктивным.

P.S. Код должен быть как хорошо написанная книга. Самодокументированный код.

1 голос
/ 24 сентября 2017

есть преимущества для assertThat по сравнению с assertEquals -
1) более читабельный
2) больше информации о сбое
3) ошибки времени компиляции, а не ошибки времени выполнения
4) гибкость при написании условий теста
5) portable - если вы используете hamcrest - вы можете использовать jUnit или TestNG в качестве базового фреймворка.

...