如何使用JUnit测试java反射代码

时间:2016-10-07 07:04:03

标签: java unit-testing reflection junit junit4

我有一个通过反射调用方法的java类。该方法创建数据库连接并执行数据库操作。我想用junit测试我的思考代码。有没有办法做到这一点?

请在下面找到我的代码段。

    Class DaoImpl {

    public void setResult(String result) {
        this.result = result
    }

    public String getResult() {
        return this.result;
    }

    public void doDBoperation() {
        Connection connection = getConnection();
        Statement st = connection.createStatement();
        ResultSet rs = st.executeQuery("Select column_name from table");
        if(rs.next()) {
            result = "value";
        }
    }
}


Class ReflectionClass {

    public void invoke() {
        Class<?> noParam = {};

        Class<?> clazz = Class.forname("DaoImpl");
        Method method = clazz.getDeclaredMethod("doDBoperation", noParam);

        method.invoke(clazz.getNewInstance);
        System.out.println("This is it");
    }
}

如何为我的ReflectionClass编写JUnit测试用例?

2 个答案:

答案 0 :(得分:0)

没有真正的纯单元测试&#34;测试方式* ReflectionClass **。通常,您可以通过向生产代码提供该类的模拟实例来进行单元测试;然后你可以使用模拟框架来验证是否调用了预期的方法。

但在您的情况下,您创建的代码只需进行测试(如果您想了解如何处理该部分,则可能需要观看这些videos)。你基本上打电话给#34; new&#34;直接在您的生产代码中;因此无法插入模拟对象。除此之外,你也不能嘲笑那些反思方法。

可能测试此代码的唯一选择是将Mokito与PowerMock一起使用。但我不是该领域的专家,也不能向你保证它会起作用。

我给你的建议:先退一步,然后想一想你是否可以远离使用反射,或者至少:在这里分开关注点。因为如上所述:您的生产设计看起来怪异;而不是花费数小时来得到单位测试;你应该花一点时间来改进你的设计! &#34;难以测试&#34;通常意味着&#34;设计可以改进&#34;!

含义:首先创建一个接口,表示您要测试的功能。然后将 ReflctionClass 的生产代码分开,如:

  1. 一部分负责提供该界面的实例(如果确实需要,该代码可以使用反射来完成其工作)
  2. 然后另一部分调用您想在该接口对象上调用的方法。
  3. 通过这样做,您可以获得两个部分,您可以相互独立地进行测试!

    编辑:我的意思是&#34;糟糕的设计&#34; - 为什么使用反射同时执行 - 对象创建方法调用?你看,你可以简单地将创建的对象强制转换为正确的类(至少如果你在那里定义了接口),然后对该类型对象进行普通的方法调用。

答案 1 :(得分:0)

正如@GhostCat建议PowerMockito可以用来尝试模拟DaoImpl的构造函数。这是代码:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest(ReflectionClass.class)
public class ReflectionClassTest {

  @Test
  public void invoke() throws Exception {

    DaoImpl mockedDaoImpl = PowerMockito.mock(DaoImpl.class);
    PowerMockito.whenNew(DaoImpl.class).withNoArguments().thenReturn(mockedDaoImpl);
    new ReflectionClass().invoke();
    Mockito.verify(mockedDaoImpl, Mockito.atLeastOnce()).doDBoperation();
  }
}

但是,它不起作用。当通过反射调用时,PowerMock无法模拟构造函数。