文章目录
  1. 1. 普通java类
  2. 2. 单元测试类
  3. 3. JMockit

今天对公共类进行封装的时候,其中有个private方法,虽然可以通过测试public方法来间接测试该方法,但是我更希望将该方法隔离出来单独测试,然后简单搜索了一下,发现可以通过java反射机制实现该需求。

普通java类

public class Example {
    public int multi(int x, int y) {
        return x*y;
    }

    private int add(int x, int y) {
        return x+y;
    }

    private static int sub(int x, int y) {
        return x-y;
    }
}

该类中包含public, private,和private static三个方法,下面我们分别对其编写测试用例。

单元测试类

public class ExampleTest {
    @Test
    public void test_multi() {
        Example example = new Example();
        assertEquals(15, example.multi(3, 5));
    }

    @Test
    public void test_add() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Example example = new Example();
        Method add = example.getClass().getDeclaredMethod("add", int.class, int.class);
        add.setAccessible(true);
        assertEquals(10, add.invoke(example, 2, 8));
    }
    @Test
    public void test_sub() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Method sub = Example.class.getDeclaredMethod("sub", int.class, int.class);
        sub.setAccessible(true);
        assertEquals(-6, sub.invoke(null, 2, 8));
    }
}

其中对于private static方法,当然也可以像add一样测试,但是使用static特定的反射形式更合理一些。javadoc中有规定:

If the underlying method is static, then the specified obj argument is ignored. It may be null.

JMockit

不要重复造轮子,既然单元测试可以使用junit,那测试private方法也会有工具帮助我们完成工作,那就是JMockit。

借助工具,我们的测试用例可以写成下面的样子:

public class ExampleJMockitTest {

    @Test
    public void test_sub() {
        assertEquals(-6, Deencapsulation.invoke(Example.class, "sub", 2, 8));
    }

    @Test
    public void test_add() {
        Example example = new Example();
        assertEquals(10, Deencapsulation.invoke(example, "add", 2, 8));
    }
}

明显代码量有所减少,其实JMockit也是使用java反射帮我们完成了对private方法的测试。更多关于JMockit的内容可以参考官方文档

文章目录
  1. 1. 普通java类
  2. 2. 单元测试类
  3. 3. JMockit