Search code examples
javaspring-bootjdbctemplatespyjunit-jupiter

Simulate jdbcTemplate query Exception with Spy (junit5)


I'm using Spy and not Mock because I want the regular functionality in other methods. I want to simulate an exception while calling jdbcTemplate query.

JdbcTemplate.query prototype is public <T> List<T> query(String sql, RowMapper<T> rowMapper) throws DataAccessException and I call it like this:

jdbcTemplate.query("select 1 from dual", new SingleColumnRowMapper<>());

Here is my spy decalration:

@SpyBean
JdbcTemplate jdbcTemplate;

And here is the test:

@Test
void testDbIsDown() {
    when(jdbcTemplate.query(anyString(),any(SingleColumnRowMapper.class)))
            .thenThrow(new DataAccessResourceFailureException("s"));
    Health health = dbServiceValidator.health();
    assertThat(health.getStatus().getCode())
            .isEqualTo(Health.down().build().getStatus().getCode());
}

Running the “when” throw an exception java.lang.IllegalArgumentException: RowMapper is required While it’s works fine with @MockBean (instead of SpyBean that I want).

Why it’s working with mock but not with spy? What should I do to make it work with @Spy?

P.S. Same behavior with

when(jdbcTemplate.query(anyString(),any(RowMapper.class)))
        .thenThrow(DataAccessException.class);

Solution

  • When you using Spring Boot @MockBean or @SpyBean, both are Spring aware.

    To understand Mockito mock and spy, check the Mockito series from Baeldung, esp. Injecting Mockito Mocks into Spring Beans.

    I have written a simple testing code sample of using Mockito and Spring(not Spring Boot), spy on the real instance, and mock and replace methods by stubbing.

    The usage of doNoting, doAnswer, doReturn, doThrow are similar, call these methods on stubbing behaviors to return a result before executing the method of the spy object.

    If you are interested, check the testing code samples about Mockito from my github, eg. this test.