我正在JUnit中编写单元测试,但是无法成功覆盖捕获SQLException并返回null对象的特定方法的分支。 这是我正在测试的课程:
@Component
public class UnitOfMeasureRowMapper implements RowMapper<UnitOfMeasure> {
public UnitOfMeasure mapRow(final ResultSet resultSet, final int rowNumber) throws SQLException {
UnitOfMeasure unitOfMeasure = new UnitOfMeasure();
try {
unitOfMeasure.setUnitOfMeasureId(resultSet.getInt("UNITOFMEASUREID"));
unitOfMeasure.setOwnerUserId(resultSet.getInt("USERID"));
unitOfMeasure.setName(resultSet.getString("NAME"));
unitOfMeasure.setDescription(resultSet.getString("DESCRIPTION"));
} catch (SQLException e) {
unitOfMeasure = null;
}
return unitOfMeasure;
}
}
这是我编写的JUnit测试,用于覆盖上述方法的第二个分支(具有来自测试类的适当上下文):
private static UnitOfMeasure testUnitOfMeasure;
private static UnitOfMeasureRowMapper mockRowMapper;
public void setUp() throws Exception {
mockRowMapper = mock(UnitOfMeasureRowMapper.class);
mockResultSet = mock(ResultSet.class);
}
@Test(expected=SQLException.class)
public void testUnitOfMeasureRowMapperFailsSQLException() throws SQLException {
when(mockRowMapper.mapRow(mockResultSet, 1)).thenReturn(null);
testUnitOfMeasure = mockRowMapper.mapRow(mockResultSet, 1);
}
我认为问题出在最后一行;不知怎的,我需要强制一个SQLException。问题是,我不知道怎么也找不到答案。有人可以帮忙吗?
答案 0 :(得分:4)
如果我理解这个问题,那么被测试的课程是 UnitOfMeasureRowMapper 。如果这是真的,那么你不想在你的测试中模拟它,否则你正在测试一个模拟! 在你的JUnit中测试的是 UnitOfMeasureRowMapper#mapRow 的行为,当你给它 ResultSet 时,它会在方法执行期间抛出一个SQLException。然后,您希望此方法返回null。 我会这样写:
private ResultSet mockResultSet;
private RowMapper<UnitOfMeasure> rowMapper = new UnitOfMeasureRowMapper();
public void setUp() throws Exception {
mockResultSet = mock(ResultSet.class);
}
@Test
public void mapRow_SHOULD_return_null_WHEN_resultSet_throws_a_SQLException() {
when(mockResultSet.getInt(anyString()).thenThrow(new SQLException());
assertThat(mockRowMapper.mapRow(mockResultSet, 1), nullValue());
}
正如Samuel在他的回答中所建议的那样,你可以设置一个用于抛出SQLException的结果集的方法,然后在你的JUnit中检查mapRow方法是否按预期返回null。在这里,你没有测试结果集的行为,因此可以嘲笑它以实现在某些环境下通常会产生的行为,否则会很痛苦。模拟结果集行为使您可以专注于测试RowMapper行为。
您正在测试实现 RowMapper 的 UnitOfMeasureRowMapper 。所以在你的JUnit中有一个 rowMapper 属性,我更喜欢通过它的界面看到它。我喜欢粗暴地调用 UnitOfMeasureRowMapper 的构造函数,因为我想保持我的JUnit尽可能简单。
答案 1 :(得分:0)
设置模拟getInt
的方法之一(可能ResultSet
?)以抛出异常。你没有指定你正在使用的模拟框架,所以我无法告诉你确切的语法。