Как заставить SQLException в JUnit


Я пишу модульные тесты в 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. Проблема в том, что я не знаю, как это сделать. и не смогли найти ответа. Кто-нибудь может помочь?

2 3

2 ответа:

Если я хорошо понимаю вопрос, то тестируемый класс-это 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());
}

Как предположил Самуил в своем ответ: вы можете задать один из методов результирующего набора, который вы используете для создания SQLException, а затем проверить в своем JUnit, что метод mapRow возвращает null, как и ожидалось. Здесь вы не тестируете поведение результирующего набора, поэтому его прекрасно использовать для достижения поведения, которое он обычно имел бы при некоторых условиях, которые было бы болезненно получить в противном случае. Насмешка над поведением результирующего набора позволяет сосредоточиться на тестировании поведения RowMapper.

Вы испытываете UnitOfMeasureRowMapper , который реализуетRowMapper . Так что есть свойствоrowMapper в вашем JUnit, и я предпочитаю видеть его через интерфейс. Мне нравится грубо вызывать конструкторUnitOfMeasureRowMapper , потому что я хочу, чтобы мой JUnit был максимально простым.

Задайте один из методов (может быть, getInt?) вашего макета ResultSet, чтобы бросить исключение. Вы не указали, какой фреймворк насмешки вы используете, поэтому я не могу сказать вам точный синтаксис.