我有一个通过反射调用方法的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的生产代码分开,如:
- 一部分负责提供该接口的实例(如果确实需要,该代码可以使用反射来完成其工作)
- 另一部分然后调用你想在该接口对象上调用的方法。