如何模拟junit覆盖的异常?

时间:2015-11-16 17:23:42

标签: java unit-testing junit mockito

我有一个导致异常的类。我想要的是模拟该异常但是覆盖范围(因此需要间谍)我如何使用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);
    }

上面会有效,但不会被覆盖。

2 个答案:

答案 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;)。它失败很快,并且很容易理解我正在尝试做什么。