Статьи

JUnit и Hamcrest: улучшение assertEquals

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

Следующий листинг кода — это простой класс IntegerArithmetic котором есть один метод, который необходимо протестировать модулем.

IntegerArithmetic.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package dustin.examples;
 
/**
 * Simple class supporting integer arithmetic.
 *
 * @author Dustin
 */
public class IntegerArithmetic
{
   /**
    * Provide the product of the provided integers.
    *
    * @param integers Integers to be multiplied together for a product.
    * @return Product of the provided integers.
    * @throws ArithmeticException Thrown in my product is too small or too large
    *     to be properly represented by a Java integer.
    */
   public int multipleIntegers(final int ... integers)
   {
      int returnInt = 1;
      for (final int integer : integers)
      {
         returnInt *= integer;
      }
      return returnInt;
   }
}

Общий подход для тестирования одного аспекта вышеуказанного метода показан ниже.

01
02
03
04
05
06
07
08
09
10
11
12
/**
 * Test of multipleIntegers method, of class IntegerArithmetic, using standard
 * JUnit assertEquals.
 */
@Test
public void testMultipleIntegersWithDefaultJUnitAssertEquals()
{
   final int[] integers = {2, 3, 4 , 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
   final int expectedResult = 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 *13 * 14 * 15;
   final int result = this.instance.multipleIntegers(integers);
   assertEquals(expectedResult, result);
}

В довольно типичном примере модульного теста, показанном выше, assertEquals JUnit вызывается бегло из-за статического импорта org.junit.Assert. * (Не показано). Тем не менее, последние версии JUnit ( JUnit 4.4+ ) начали включать в себя средства сравнения ядра Hamcrest, и это позволяет проводить еще более быстрое тестирование, как показано в следующем фрагменте кода.

01
02
03
04
05
06
07
08
09
10
11
12
/**
 * Test of multipleIntegers method, of class IntegerArithmetic, using core
 * Hamcrest matchers included with JUnit 4.x.
 */
@Test
public void testMultipleIntegersWithJUnitHamcrestIs()
{
   final int[] integers = {2, 3, 4 , 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
   final int expectedResult = 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 *13 * 14 * 15;
   final int result = this.instance.multipleIntegers(integers);
   assertThat(result, is(expectedResult));
}

В этом примере JUnit assertThat (также доступный как часть статического импорта org.junit.Assert.* с JUnit 4.4 ) используется вместе с включенным основным соответствием Hamcrest is() . Это, конечно, дело вкуса, но я предпочитаю этот второй подход как более читаемый для меня. Утверждение, что что-то (результат) является чем-то другим (ожидаемым), кажется более читабельным и более свободным, чем старый подход. Иногда бывает сложно вспомнить, нужно ли сначала перечислять ожидаемый или фактический результат при использовании assertEquals и комбинации assertThat и is() делает немного меньше работы, когда я пишу и читаю тесты. Даже немного меньше работы, особенно если умножить на многочисленные тесты, можно только приветствовать.

Ссылка: Улучшение AssertEquals с JUnit и Hamcrest от нашего партнера JCG Дастина Маркса в блоге Inspired by Actual Events .