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