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



我有一个通过反射调用方法的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测试用例?

@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不能模拟构造函数。

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

但是在您的例子中,您创建的代码只是难以测试(如果您想了解如何解决这部分问题,您可能想观看这些视频)。你基本上是直接在产品代码中调用"new";因此,无法插入模拟对象。除此之外,你也不能模仿那些反射方法。

可能测试此代码的唯一选择是将Mokito与PowerMock一起使用。但我不是这方面的专家,也不能保证它一定有效。

我给你的建议是:先退后一步,看看你是否可以让远离使用反射,或者至少:在这里分离关注点。因为如前所述:你的产品设计看起来很奇怪;而不是花几个小时进行单元测试;你应该花一小部分时间来改进你的设计!"难以测试"通常意味着"设计可以改进"!

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

  1. 一部分负责提供该接口的实例(如果确实需要,该代码可以使用反射来完成其工作)
  2. 另一部分然后调用你想在该接口对象上调用的方法。
通过这样做,您可以获得两个可以彼此独立测试的部分!编辑:我所说的"糟糕的设计"是什么意思?为什么你使用反射来同时做对象创建方法调用?您可以简单地将创建的对象强制转换为其正确的类(至少如果在那里定义了接口),然后对该类型化对象执行普通的方法调用。

相关内容

  • 没有找到相关文章

最新更新