1. 概述

JukitoJUnitGuiceMockito 三大工具的强力组合——专门用于简化同一接口多种实现的测试场景。

本文将探讨作者如何巧妙融合这三个库,帮我们大幅减少样板代码,让测试更灵活、更简洁。

2. 环境配置

首先添加 Maven 依赖:

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

最新版本可在 Maven Central 获取。

3. 接口多实现测试

要理解 Jukito 的威力,先定义一个简单的 Calculator 接口:

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 注解会在运行时自动注入所有实现,并分别执行测试

运行结果验证:

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

✅ 确实生成了 2 个独立测试用例

4. 笛卡尔积测试

添加测试数据组合类:

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

    // 标准构造器/getter
}

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 注解会自动生成笛卡尔积组合

  • 2 个 Calculator 实现 × 3 组测试数据 = 6 个测试用例

实际运行结果:

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

(原文此处为 8,但按计算应为 6,可能是笔误,我们保留原文数据)

⚠️ 踩坑提醒:笛卡尔积会导致测试数量爆炸式增长!
例如:3 个参数各绑定 4 种组合 → 4³ = 64 次执行
5 个组合 → 5³ = 125 次执行

5. 分组测试

通过命名绑定实现分组测试:

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

分组测试用例:

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

输出结果(顺序不保证):

even 2
even 4
even 6
odd 1
odd 3
odd 5

6. 总结

Jukito 通过组合测试用例,用极简代码实现了强大的测试覆盖能力。核心优势:

  • ✅ 自动处理多实现测试
  • ✅ 灵活的笛卡尔积组合
  • ✅ 便捷的分组测试机制

完整示例代码见 GitHub 项目


原始标题:Introduction to Jukito