英文:
Simulate jdbcTemplate query Exception with Spy (junit5)
问题
我使用 Spy 而不是 Mock,因为我希望其他方法中保留常规功能。我想在调用 jdbcTemplate 查询时模拟异常。
JdbcTemplate.query 的原型是 public <T> List<T> query(String sql, RowMapper<T> rowMapper) throws DataAccessException
,我像这样调用它:
jdbcTemplate.query("select 1 from dual", new SingleColumnRowMapper<>());
这是我的 Spy 声明:
@SpyBean
JdbcTemplate jdbcTemplate;
这是测试部分:
@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());
}
运行 "when" 时会抛出异常 java.lang.IllegalArgumentException: RowMapper is required
,但是如果使用 @MockBean(而不是我想要的 SpyBean)则正常运行。
为什么使用模拟(mock)可以工作,但使用 Spy 不能?我应该怎么做才能让它在 @Spy 下工作?
附注:使用以下代码也会产生相同的行为:
when(jdbcTemplate.query(anyString(), any(RowMapper.class)))
.thenThrow(DataAccessException.class);
英文:
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);
答案1
得分: 1
使用Spring Boot的@MockBean或@SpyBean时,两者都与Spring相关。
要了解Mockito的模拟和spy功能,请查看来自Baeldung的Mockito系列教程,尤其是将Mockito模拟对象注入Spring Bean中。
我编写了一个关于使用Mockito和Spring(不是Spring Boot)的简单测试代码示例,在该示例中对真实实例进行了spy,并通过存根化(mock)和替换方法来进行模拟。
doNothing
、doAnswer
、doReturn
、doThrow
的使用方式类似,在存根化行为上调用这些方法可以在执行spy对象的方法之前返回结果。
如果你感兴趣的话,可以从我的GitHub中查看有关Mockito的测试代码示例,例如这个测试。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论