Junit4: Улучшение: поддержка BigDecimal для assertEquals ().

Созданный на 25 мар. 2010  ·  27Комментарии  ·  Источник: junit-team/junit4

Использование JUnit для проверки значений BigDecimal всегда является больным местом. Это потому, что BigDecimal учитывает точность с помощью equals (), но игнорирует ее в compareTo (). Лучшим способом справиться с этим будет новый метод assertEquals, который позволяет при необходимости оценивать точность. Вы также можете добавить альтернативный метод, принимающий сообщение:

public static void assertEquals (ожидается BigDecimal, фактическое BigDecimal, логическое значение precisionMatters) {
if (precisionMatters) {
Assert.assertEquals (ожидаемый, фактический);
} еще {
Assert.assertEquals (0, ожидаемый .compareTo (фактический));
}
}

Самый полезный комментарий

Вы пробовали использовать comparesEqualTo ?

Все 27 Комментарий

Было бы легко собрать вилку или заплатку; Я был бы готов сделать это, если это будет уместно.

Я бы предпочел иметь утверждение assertNumericallyEqualTo, чем логический флаг, переданный в assertEquals.

Хорошее имя. Я бы сократил его до assertNumericallyEquals ().

Хотя я согласен с мнением, я не уверен, что наличие другого метода assert с другим именем действительно поможет устранить путаницу, особенно среди людей, которые совершенно не осознают разницу или сами действительно не сталкивались с проблемой. То есть, если бы я не читал этот выпуск, я бы пошел дальше и использовал assertEquals() для BigDecimal . В общем случае он действительно будет работать так, как рекламируется - он будет работать точно так, как работает BigDecimal#equals() . Я бы даже сказал, что это хорошо - это заставляет кого-то осознать, что BigDecimal#equals() сравнивает и значение, и масштаб, тогда, возможно, это не то, чего они пытались достичь - хотя в других случаях я утверждаю это. _является_. Я имею в виду, что в некоторых случаях мы хотим проверить, что фактическое значение, возвращаемое методом, _ точно_ 'равно' ожидаемому значению (а не просто логически / численно равно). Иными словами: что дает assertNumericallyEquals() (помимо краткости), чего не дает assertEquals(0, actual.compareTo(expected)) ? Лично я бы, вероятно, создал сопоставитель Hamcrest и пошел бы assertThat(actual, isNumericallyEqualTo(expected)) если он мне нужен достаточно часто - плюс, его можно использовать везде, где можно использовать сопоставители Hamcrest (среди прочего, проверка данных).

Извините за позднее взвешивание, но мое личное мнение близко к Алистеру.

Иными словами: что дает assertNumericallyEquals() (помимо краткости), чего не дает assertEquals(0, actual.compareTo(expected)) ?

Более четко передает намерение? Подход Hamcrest Matcher меня устраивает.

Джеффри,

Вы хотите сказать, что хорошо пишете этот матчер для своего собственного проекта или хотите, чтобы он поставлялся с hamcrest? Или JUnit, но не hamcrest?

Любое или все из вышеперечисленного - большинство проектов, которые я пишу, в конечном итоге имеют несколько настраиваемых сопоставителей hamcrest. Наличие общих случаев, охватываемых Hamcrest и / или JUnit, экономит немного времени, но для меня это тоже не очень распространенный случай.

Небольшой замечание о менее полезных сообщениях об ошибках. Я только что преобразовал свои вызовы Assert.assertEquals в Assert.assertTrue, столкнувшись с ошибками при сравнении BigDecimals с Assert.assertEquals. Конечно, теперь мои тесты терпят неудачу из-за ошибки типа «логическая ошибка теста», не сообщая мне, каковы были значения. Таким же образом assertEquals (0, actual.compareTo (ожидаемый)) будет регистрировать, например, «ожидаемый 0, но получил: 1», когда гораздо более полезное сообщение об ошибке будет от assertNumericallyEquals (фактическое, ожидаемое) будет «ожидается 12,45, но получено : 123 »(фактические значения« фактических »и« ожидаемых »аргументов).

http://www.bssd.eu/blog/?p=113 также представляет собой интересное чтение.

assertEquivalent из https://github.com/KentBeck/junit/pull/228 должен решить эту проблему.

Спасибо, dsaff. Эта работа выглядит великолепно. Я не делал этого раньше, означает ли это, что мне нужно получить исходный код junit, самостоятельно объединить этот запрос на перенос и создать собственную сборку?

Из справки на http://help.github.com/send-pull-requests/ кажется, что мне следует:

git clone https://github.com/KentBeck/junit.git
cd junit

а затем добавьте пульт для запроса на перенос, затем либо выберите, либо объедините, либо и то, и другое.

Учитывая, что это похоже на запрос на перенос, то есть не официальный junit, разумно ли использовать его в приложении? Есть ли шанс, что это выйдет за пределы основного junit, и у меня возникнут проблемы с отправкой моего кода другим, для кого он не будет построен?

Никфенвик,

Да, вы на правильном пути в отношении того, как это сделать сейчас. Я намерен объединить этот запрос в ветку 4.10, но у исходного автора возникли проблемы с получением объединяемого статуса git. Если у вас есть время сделать миру одолжение, вы можете форкнуть репозиторий KentBeck, объединить все и отправить запрос на вытягивание для ветки 4.10, чтобы всем было проще (если это звучит популярно, я мог бы даже развернуть когда-нибудь загрузите банку предварительного просмотра 4.10).

Я действительно никогда не делал этого раньше :) Итак, я разветвил репо и клонировал [email protected] : neekfenwick / junit.git на свой локальный компьютер (у меня уже есть учетная запись github и настроены ключи ssh) и добавил пульт для репо, из которого я его раздвоил:

git remote add upstream https://github.com/KentBeck/junit.git

На всякий случай я разветвился, чтобы можно было объединить запрос на перенос где-нибудь, кроме HEAD:

git branch merge_pullreq_228
git checkout merge_pullreq_228

Теперь документы, которые я могу найти, говорят: «Теперь объедините запрос на перенос в свою ветку». Я вижу коммиты для pull 228 на https://github.com/KentBeck/junit/pull/228/commit, но не могу их объединить:

[neek junit (merge_pullreq_228)]$ git merge 57b49344
fatal: '57b49344' does not point to a commit

Поскольку запрос на перенос не для моего собственного репо / ветки, я не могу использовать инструменты слияния в веб-интерфейсе github (AFAIK).

Правильно ли я думаю, что вы хотите, чтобы я объединил 7 коммитов в мою собственную ветку и заставил ее создавать / проходить модульные тесты? Не могли бы вы объяснить, что нужно сделать, чтобы объединить один из этих коммитов, чтобы заставить меня продолжить свой путь?

Правильно, вы не можете использовать инструменты веб-слияния. Я считаю, что должно работать:

git remote добавить leet3lite https://github.com/leet3lite/junit.git

А потом из своего филиала позвоните

git pull leet3lite master

К сожалению, я обычно забываю одну вещь, описывая, как использовать git «по телефону», поэтому дайте мне знать, работает ли это для вас.

А, я понимаю, мне не нужно объединять каждый из этих коммитов .. В ветке master leet3lite они уже есть, и проблема заключается в слиянии этой работы с исходным мастером.

Кажется, есть конфликты слияния между этой веткой и HEAD. Думаю, в этом весь смысл этого упражнения.

[neek junit (merge_pullreq_228)]$ git remote add leet3lite https://github.com/leet3lite/junit.git
[neek junit (merge_pullreq_228)]$ git pull leet3lite master
remote: Counting objects: 100, done.
remote: Compressing objects: 100% (39/39), done.
remote: Total 85 (delta 34), reused 77 (delta 26)
Unpacking objects: 100% (85/85), done.
From https://github.com/leet3lite/junit
 * branch            master     -> FETCH_HEAD
Auto-merging acknowledgements.txt
CONFLICT (content): Merge conflict in acknowledgements.txt
Auto-merging src/main/java/org/junit/Assert.java
Auto-merging src/test/java/org/junit/tests/AllTests.java
CONFLICT (content): Merge conflict in src/test/java/org/junit/tests/AllTests.java
Automatic merge failed; fix conflicts and then commit the result.
[neek junit (merge_pullreq_228|MERGING)]$ 

Если это кажется вам разумным, я займусь этим завтра. Здесь почти полночь.

Похоже, вы попали в нужное место. Подтверждения.txt и AllTests.java часто затрагиваются, обычно просто добавлением, поэтому операция слияния, вероятно, представляет собой простой акт включения всех строк, добавленных на обоих путях.

Большое спасибо за продвижение вперед.

Думаю, это было исправлено 2 года назад.

dsaff - Нет ...?

Не в 4.11; (мне тоже нужна эта функция

Обсуждение assertEquivalent() переместилось в # 228, а после этого, я думаю, оно переместилось в # 376, где мы решили, что на самом деле Hamcrest должен решить эту проблему.

@ junit-team / junit-committers есть ли возражения против того, чтобы я закрыл это?

Никаких возражений с моей стороны.

Ой, фрейдистский щелчок. :-) Здесь нет возражений.

Хорошо. Итак, закрытие.

Я не думаю, что использование подборщика hamcrest исправит эту проблему. Например этот код:

   assertThat(product.getRating(), is(equalTo(new BigDecimal("2.3"))));

даст такой результат:

Expected: is <2.3>
     but: was <2.30000>

Я думаю, что junit или hamcrest все еще нуждается в методе isNumericEquivalent .

Вы пробовали использовать comparesEqualTo ?

Да, comparesEqualTo действительно работает. Спасибо.

Вот шпаргалка, которую я создал некоторое время назад:
http://www.marcphilipp.de/blog/2013/01/02/hamcrest-quick-reference/

Была ли эта страница полезной?
0 / 5 - 0 рейтинги