如何进行单元测试无法实例化的对象?因为目前我有一个将ResultSet转换为对象的方法,但我不确定这是否违反任何编程原则。
public CItem convert(ResultSet rs) {
CItem ci = new CItem ();
try {
ci.setHinumber(rs.getString("id"));
ci.setHostname(rs.getString("sysname"));
ci.setOs(rs.getString("zos"));
ci.setTenant(rs.getString("customer_name"));
//ci.setInstallation(rs.getField("installation_name"));
} catch (SQLException e) {
e.printStackTrace();
}
return ci;
}
我是否需要寻找一种不同的方法来解决这个问题,因为它无法进行单元测试?或者我可以以某种方式伪造ResultSet对象。
任何帮助都将不胜感激。
答案 0 :(得分:14)
您可以简单地模拟ResultSet
为每个字段提供值,并检查结果是否包含您期望的内容。
例如使用Mockito,您的测试将是这样的:
@RunWith(MockitoJUnitRunner.class)
public class SomeClassTest {
@Mock
private ResultSet resultSet;
@Test
public void testConvert() throws SQLException {
// Define the behavior of the mock for each getString method's call
Mockito.when(resultSet.getString("id")).thenReturn("myId");
Mockito.when(resultSet.getString("sysname")).thenReturn("myHost");
Mockito.when(resultSet.getString("zos")).thenReturn("myOS");
Mockito.when(resultSet.getString("customer_name")).thenReturn("myCustomerName");
// Launch the method against your mock
SomeClass someClass = new SomeClass();
CItem item = someClass.convert(resultSet);
// Check the result
Assert.assertNotNull(item);
Assert.assertEquals("myId", item.getHinumber());
Assert.assertEquals("myHost", item.getHostname());
Assert.assertEquals("myOS", item.getOs());
Assert.assertEquals("myCustomerName", item.getTenant());
}
}
答案 1 :(得分:1)
如果您的类不处理数据库访问,则接受ResultSet作为参数感觉就像代码味道。
您可以使用像Mockito或Power Mock这样的模拟框架来创建模拟ResultSet。但是,您不应该模拟您没有编写的类(即库/ JDK类)。
假设您的ResultSet表示Order表中的某些订单数据。这种方法真正需要的是“订单数据”,您不必担心此时从何处以及从何处获取此数据。所以你应该理想地定义这样的界面。
interface OrderRepository {
OrderData get();
}
然后你可以有一个实现这个接口JDBCOrderRepository
的类来处理ResultSet。而您的方法('convert')现在将接受OrderRepository而不是ResultSet。为了测试您的方法,您可以更轻松地模拟OrderRepository而不是ResultSet。
现在你将如何测试JDBCOrderRepository
?好吧,可能你应该用一个运行的DB实例来测试它,这实际上是一个集成测试。