«1. Обзор

Jukito — это объединенная мощь JUnit, Guice и Mockito, используемая для упрощения тестирования нескольких реализаций одного и того же интерфейса.

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

2. Настройка

Сначала мы добавим в наш проект следующую зависимость:

<dependency>
    <groupId>org.jukito</groupId>
    <artifactId>jukito</artifactId>
    <version>1.5</version>
    <scope>test</scope>
</dependency>

Мы можем найти последнюю версию на Maven Central.

3. Различные реализации интерфейса

Чтобы понять мощь Jukito, мы собираемся определить простой интерфейс калькулятора с помощью метода Add:

public interface Calculator {
    public double add(double a, double b);
}

И мы собираемся реализовать следующий интерфейс:

public class SimpleCalculator implements Calculator {

    @Override
    public double add(double a, double b) {
        return a + b;
    }
}

Нам также нужна другая реализация:

public class ScientificCalculator extends SimpleCalculator {
}

Теперь давайте воспользуемся Jukito для тестирования обеих наших реализаций:

@RunWith(JukitoRunner.class)
public class CalculatorTest {

    public static class Module extends JukitoModule {

        @Override
        protected void configureTest() {
            bindMany(Calculator.class, SimpleCalculator.class, 
              ScientificCalculator.class);
        }
    }

    @Test
    public void givenTwoNumbers_WhenAdd_ThenSumBoth(@All Calculator calc) {
        double result = calc.add(1, 1);
 
        assertEquals(2, result, .1);
    }
}

В этом примере мы видим JukitoModule, во всех указанных реализациях.

Аннотация @All принимает все привязки одного и того же интерфейса, созданные JukitoModule, и запускает тест со всеми различными реализациями, внедренными во время выполнения.

Если мы запустим тесты, мы увидим, что действительно выполняются два теста вместо одного:

Tests run: 2, Failures: 0, Errors: 0, Skipped: 0

4. Декартово произведение

Давайте теперь добавим простой вложенный класс для различных комбинаций тестов для нашего Add method:

public static class AdditionTest {
    int a;
    int b;
    int expected;

    // standard constructors/getters
}

Это расширит количество тестов, которые мы можем запустить, но сначала нам нужно добавить дополнительные привязки в наш метод configureTest:

bindManyInstances(AdditionTest.class, 
  new AdditionTest(1, 1, 2), 
  new AdditionTest(10, 10, 20), 
  new AdditionTest(18, 24, 42));

И, наконец, мы добавим еще один тест в наш набор: ~ ~~

@Test
public void givenTwoNumbers_WhenAdd_ThenSumBoth(
  @All Calculator calc, 
  @All AdditionTest addTest) {
 
    double result = calc.add(addTest.a, addTest.b);
 
    assertEquals(addTest.expected, result, .1);
}

Теперь аннотация @All будет производить декартово произведение различных комбинаций между различными реализациями интерфейса калькулятора и экземплярами AdditionTest.

Мы можем посмотреть на возросшее количество тестов, которые он теперь производит:

Tests run: 8, Failures: 0, Errors: 0, Skipped: 0

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

Время выполнения всех тестов будет расти линейно с количеством выполнений. то есть: тестовый метод с тремя параметрами с аннотацией @All и четырьмя привязками на параметр будет выполняться 4 x 4 x 4 = 64 раза.

Наличие пяти привязок для одного и того же метода тестирования приведет к 5 x 5 x 5 = 125 выполнениям.

5. Группировка по именам

Последняя функция, которую мы обсудим, это группировка по имени:

bindManyNamedInstances(Integer.class, "even", 2, 4, 6);
bindManyNamedInstances(Integer.class, "odd", 1, 3, 5);

Здесь мы добавили несколько именованных экземпляров целочисленного класса в наш метод configureTest, чтобы продемонстрировать, что может сделать с этими группами.

Теперь добавим еще несколько тестов:

@Test
public void givenEvenNumbers_whenPrint_thenOutput(@All("even") Integer i) {
    System.out.println("even " + i);
}

@Test
public void givenOddNumbers_whenPrint_thenOutput(@All("odd") Integer i) {
    System.out.println("odd " + i);
}

В приведенном выше примере будут напечатаны шесть строк «четные 2», «четные 4», «четные 6», «нечетные 1», « «нечетные 3», «нечетные 5».

Имейте в виду, что их порядок не гарантируется во время выполнения.

6. Заключение

В этом кратком руководстве мы рассмотрели, как Jukito позволяет использовать весь набор тестов, предоставляя достаточное количество комбинаций тестовых случаев.

Полный пример можно найти на GitHub.