4

I'm writing unit tests in JUnit, but have not been able to successfully cover a branch of a particular method that catches a SQLException and returns a null object. This is the class I'm testing:

@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;
    }
}

This is the JUnit test that I have written to cover the second branch of the above method (with appropriate context from the test class):

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);
    }

I think the problem is with the last line; somehow I need to force a SQLException. The problem is, I don't know how and haven't been able to find an answer. Can anyone help?

RustyTheBoyRobot
  • 5,891
  • 4
  • 36
  • 55
James Dunn
  • 8,064
  • 13
  • 53
  • 87

2 Answers2

4

If I understand the question well, the class under test is UnitOfMeasureRowMapper. If this is true, then you don't want to mock it in your test, otherwise you are testing a mock! What is under test in your JUnit, is the behavior of UnitOfMeasureRowMapper#mapRow when ResultSet you give it throws a SQLException during the execution of the method. Then you want this method to return null. I would write it like this:

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());
}

As suggested Samuel in his answer, you may set one of the method of the result set you use to throw a SQLException, and then check in your JUnit that the mapRow method returns null as expected. Here you are not testing the behavior of the result set, so its fine to mock it to achieve a behavior it would normally have under some circunstancies that would be painful to obtain otherwise. Mocking the result set behavior lets you focus on testing the RowMapper behavior.

You are testing the UnitOfMeasureRowMapper that implements RowMapper. So have a rowMapper property in your JUnit, and I prefer to see it through its interface. I like to brutally call the constructor of UnitOfMeasureRowMapper because I want to keep my JUnit as simple as they can be.

Mikayil Abdullayev
  • 12,117
  • 26
  • 122
  • 206
Alban
  • 1,915
  • 1
  • 14
  • 17
  • 1
    It turns out this whole time I simply needed to use thenThrow. I'd been banging my head trying to make it work with thenReturn. Thanks! – James Dunn Oct 05 '12 at 18:18
0

Set one of the methods (maybe getInt?) of your mock ResultSet to throw the exception. You didn't specify what mocking framework you're using so I can't tell you the exact syntax.

Samuel Edwin Ward
  • 6,526
  • 3
  • 34
  • 62
  • @ Samuel Edwin Ward and Alban: Thanks, good catch. I am using mockito, and I should have specified that. Also I have been working on a bunch of other coding and haven't been able to get back to this. Hopefully soon I'll get back to you both and let you know what worked. Thanks! – James Dunn Oct 05 '12 at 16:49