我有一个导致异常的类。我想要的是模拟该异常但是覆盖范围(因此需要间谍)我如何使用mockito进行模拟,以便Junit覆盖能够将这些异常计算在内?
例如:
private List<Data> _getSomeData(Key key) {
log.debug(logPrefix + " GetSomeData");
Connection dbc = null;
PreparedStatement st = null;
ResultSet rs = null;
String q = null;
....
try {
dbc = DataSourceUtils.getConnection(dataSource);
dbc.setAutoCommit(false);
q = "SELECT value FROM table where x = ? and y = ? and z = ?";
st = dbc.prepareStatement(q);
int ix = 1;
st.setInt(ix++, key.x);
st.setInt(ix++, key.y);
st.setInt(ix++, key.z);
rs = st.executeQuery();
while (rs.next()) {
Data data=new Data();
key.id = rs.getLong("x");
key.y = y;
....
DataList.add(data);
}
} catch (Exception e) {
throw new DbException(e, q);
} finally {
DbUtil.cleanup(log, rs, st, dbc);
}
return dataList;
}
从上面我想要的是覆盖异常。如何用覆盖率覆盖它?
Jutest - &gt;
@Test
public void testException(){
// DataImpl dataDao = new DataImpl();
// dataDao.setLog(new LogImpl());
DataImpl dataDao = Mockito.spy(new DataImpl());
Key key= new Key();
key.x = 1;
key.y = 1;
key.z = 1;
String q =
" SELECT data.* \n" +
" FROM SOME_DATA d1\n" +
" WHERE\n "+
" d1.x = ? \n " +
" AND ROUND (d1.y/ 1000 - 1) = ? \n" +
" AND MOD (d1.z, 1000) = ?";
Mockito.doThrow(new DbException(null, q)).when(invPPNDataDao)._getSomeData(Key);
}
上面会有效,但不会被覆盖。
答案 0 :(得分:1)
你需要做的是依赖注入。然后你可以模拟它并定义它的行为方式。目前,您正在构建方法中的大量对象(DataSourceUtils.getConnection(dataSource)
,new Data()
,...),这些对象难以测试。
您可以创建课程DbcProvider
:
public class DbcProvider {
public Connection newDbc() {
DataSourceUtils.getConnection(dataSource);
}
}
然后在您的测试中,您模拟DbcProvider
并将其设置为在调用newDbc
时抛出异常,然后调用您的方法_getSomeData
。
答案 1 :(得分:-1)
我假设您正在为学校做这个,这就是“覆盖”的意思,您将项目提交到评估每行代码的框架,以确保它在您的测试用例期间运行。
上述测试用例中的问题是您实际上从未运行过此代码:
} catch (Exception e) {
throw new DbException(e, q);
} finally {
DbUtil.cleanup(log, rs, st, dbc);
}
因为在您的测试用例中,您已经在_getSomeData()
方法的 之外抛出了自己的异常。为了涵盖代码的Exception e
部分,您需要在方法中使用Exception
抛出。尝试在Key
参数中传递一些值,该参数会破坏_getSomeData()
方法(可能是Null
值)。
我不认为它会在这种特定情况下起作用,但在我尝试创建异常测试用例时,我总是喜欢除以零(int error = 1/0;
)。它失败很快,并且很容易理解我正在尝试做什么。