Introduction to Jukito – Jukito简介

最后修改: 2017年 9月 23日

1. Overview


Jukito is the combined power of JUnit, Guice, and Mockito – used for simplifying testing of multiple implementations of the same interface.

JukitoJUnitGuiceMockito的综合力量 – 用于简化对同一接口的多种实现的测试。

In this article we’re going to see how authors managed to combine those three libraries to help us reduce a lot of boilerplate code, making our tests flexible and easy.


2. Setting Up


First, we’ll add the following dependency to our project:



We can find the latest version at Maven Central.


3. Different Implementations of an Interface


To start understanding the power of Jukito, we’re going to define a simple Calculator interface with an Add method:

为了开始了解Jukito的力量,我们将定义一个简单的Calculator 接口,其中有一个Add方法。

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

And we’re going to implement the following interface:


public class SimpleCalculator implements Calculator {

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

We also need another implementation:


public class ScientificCalculator extends SimpleCalculator {

Now, let’s use Jukito to test both our implementations:


public class CalculatorTest {

    public static class Module extends JukitoModule {

        protected void configureTest() {
            bindMany(Calculator.class, SimpleCalculator.class, 

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

In this example, we can see a JukitoModule, that wires in all specified implementations.


The @All annotation takes all bindings of the same interface made by the JukitoModule and runs the test with all the different implementations injected at runtime.


If we run tests, we can see that indeed two tests are run instead of one:


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

4. The Cartesian Product


Let’s now add a simple nested class for different combinations of tests for our Add method:


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

    // standard constructors/getters

This will expand the number of tests we can run, but first, we need to add additional bindings in our configureTest method:


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

And finally we add another test to our suite:


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

Now the @All annotation is going to produce the Cartesian product of the different combinations between the different implementations of the Calculator interface and the AdditionTest instances.


We can have a look at the increased number of tests it now produces:


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

We need to remember that the number of test executions increases drastically for Cartesian products.


The execution time of all tests will grow linear with the number of executions. i:e.: a test method with three parameters with an @All annotation and four bindings per parameter will be executed 4 x 4 x 4 = 64 times.

所有测试的执行时间将随着执行次数的增加而线性增长。即:一个带有@All注解的三个参数和每个参数有四个绑定的测试方法将被执行4 x 4 x 4 = 64次。

Having five bindings for the same test method will lead to 5 x 5 x 5 = 125 executions.

对同一测试方法有五个绑定,将导致5 x 5 x 5 = 125次执行。

5. Grouping by Names


The final feature we’ll discuss is the grouping by name:


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

Here, we added some named instances of the integer class to our configureTest method, to showcase what can be done with these groups.


Now let’s add some more tests:


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

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

The above example will print the six strings “even 2”, “even 4”, “even 6”, “odd 1”, “odd 3”, “odd 5”.

上面的例子将打印 “偶数2″、”偶数4″、”偶数6″、”奇数1″、”奇数3″、”奇数5 “这六个字符串。

Keep in mind that the order of these is not guaranteed at runtime.


6. Conclusion


In this quick tutorial, we took a look at how Jukito allows the use of a whole test suite, by providing just enough combinations of test cases.


The complete example can be found over on GitHub.