Должен ли я тестировать hashCode/equals/toString?

при написании классов Java нередко генерируются методы, использующие вашу IDE, такие как

  • toString()
  • equals()
  • hashCode()

но как только вы создали их с помощью IDE, они становятся частью вашей кодовой базы (в SCM), и поэтому применяются все средства измерения качества.

особенно методы equals и hashcode содержат множество условий. Если я не пишу модульные тесты, оценка покрытия кода (line -, condition -, mutation -) довольно низок, особенно если тестируемый класс не настолько велик.

некоторые инструменты покрытия поддерживают фильтрацию (например, cobertura), другие (например, jacoco) - нет. Но инструменты покрытия показывают только симптом-непроверенный код - и поэтому я не спрашиваю, подавлять / игнорировать симптом, но как бороться с основной причиной.

вопрос: Должен ли я писать юнит-тесты для этих методов?

  • если да, то какие хорошие причины для этого? А что такое разумный подход?
  • если нет, то почему бы и нет?

Я не прошу сгенерированных классов в целом, таких как JAXB pojos, WS-Clients и т. д., которые могут быть легко сгенерированы автоматически и исключены из анализа покрытия.

5 ответов


если вы генерируете эти методы, вы, вероятно, также должны генерировать тесты для него; -)

это может быть громоздким, чтобы проверить эти методы вручную, но в зависимости от того, что вы хотите обеспечить с вашими тестами, может быть стоит проверить эти методы, а также. Встречный вопрос: вы бы проверили log-операторы?

это действительно зависит от того, что вы пытаетесь достичь. Одни скажут: Не надо, другие скажут: делай.

думая о некоторых причинах, чтобы не тестировать такие методы:

  • код генерируется и может содержать множество полей. тестирование может привести к множеству различных комбинаций, которые было бы просто громоздко писать/поддерживать, и, возможно, генератор уже был протестирован достаточно хорошо? ;-)
  • вы не получаете никакого значения, реализуя тесты для него. Ваш toString() будет использоваться только журналами или отладчиком, поэтому вам все равно.
  • Вы доверяете, что сгенерированный код достаточно безопасен для hashcode и equals

причины проверить такие методы:

  • для обеспечения того, чтобы результат был ожидаемым
  • вы хотите убедиться, что если вы регенерируете эти методы, он не нарушает предыдущие использования реализации метода
  • вы используете toString()-метод, кроме регистрации и не хочу, чтобы некоторые вещи, чтобы показать там. Как заявил Халк, вы также можете убедиться, что некоторые вещи даже не появляются в системный журнал.

но эти были скорее выдуманы. В последних проектах я не тестировал toString() и equals или hashCode только seldomly, поскольку это не считалось необходимым, и все согласились.

все может сводиться к тому, насколько безопасным вы хотите, чтобы ваш код был и сколько он стоит для вас (или вашего бизнеса или вашего клиента; -))


проблема с сгенерированным IDE hashCode/equals заключается в том, что он может выйти из синхронизации с самим объектом (например, при добавлении новых полей). Поэтому я бы посоветовал создать тесты для hashCode и equals.

было бы, конечно, неоптимально писать их вручную. Вы можете использовать автоматические инструменты, такие как EqualsVerifier проект, чтобы сделать их одним лайнером.

toString-это другой зверь, поскольку у него нет определенного контракта. Если вы используете toString просто чтобы получить более приятный опыт отладки, я бы не тестировал его и просто удалил бы его из вычислений покрытия.


то же самое для внешних библиотек - вы не должны тестировать equals и hashcode методы при создании. Плагин, который проверяет покрытие, должен иметь некоторый механизм, чтобы игнорировать эти сгенерированные источники.

нет веских причин тестировать сгенерированный код, нет разницы, если это сгенерированный метод в вашем классе или в целом классе.

Если вы зависите от внешнего механизма, вы должны верить, что он создан правильно.


эти методы сами по себе бесполезны. Если вы не используете эти классы коллекций (например,HashSet / HashMap) или если вы никогда не проверяете эти экземпляры класса на равенство - вам не нужны модульные тесты. И, в этом случае, я бы просто отключил плагин, который их генерирует, как предложил @ByeBye.

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


Да, я бы проверил все это. Его недостаточно хорошо сказать, никаких тестов не требуется, поскольку они автоматически генерируются. Кто-то может легко добавить новое поле и забыть восстановить код equals/ hash и строку.

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

Как уже предлагали другие,EqualsVerifier вероятно, лучший подход для тестирования равных и хеш-код.

Что касается тестирования метода toString, попробуйте ToStringVerifier. Тест так же прост, как:

@Test
public void testToString()
{
    ToStringVerifier.forClass(User.class)
                  .withClassName(NameStyle.SIMPLE_NAME)
                  .verify();
}