4

我在 JUnit 中编写单元测试,但未能成功覆盖捕获 SQLException 并返回空对象的特定方法的分支。这是我正在测试的课程:

@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。问题是,我不知道如何也无法找到答案。任何人都可以帮忙吗?

4

2 回答 2

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 尽可能简单。

于 2012-09-29T09:18:19.363 回答
0

getInt设置您的模拟的方法之一(也许?)ResultSet以引发异常。您没有指定您使用的模拟框架,所以我无法告诉您确切的语法。

于 2012-09-29T01:06:42.510 回答