英文:
Mockito: mocking a method call that contains a lambda expression
问题
我正在为下面的Java代码创建一个单元测试,该代码从数据库获取数据,然后通过lambda将检索到的数据映射到一个列表中:
List<Pair<String, String>> list = jdbcTemplate.query(MY_QUERY, (rs, rowNum) -> {
String code = rs.getString(1);
String name = rs.getString(2);
return new Pair<String, String>(code, name);
});
这是Spring框架服务类的一部分;单元测试通过SpringJUnit4ClassRunner运行。
我已经使用Mockito来模拟jdbcTemplate对象(类型为NamedParameterJdbcTemplate)。
我尝试模拟jdbcTemplate的结果。看起来,根据方法调用,我需要模拟NamedParameterJdbcTemplate类中的这个方法:
query(String sql, RowMapper<T> rowMapper)
我尝试过以下方式:
List<Pair<String, String>> pairList = ...;
Mockito.when(jdbcTemplate.query(Mockito.anyString(), Mockito.any(RowMapper.class))).thenReturn(pairList);
但是,当我运行单元测试时,经过这行代码后,“list”变量总是为空,就好像模拟没有被触发以返回我的值。
Mockito对象肯定已经注入到类中。
打印模拟的调用显示如下:
[Mockito] Interactions of: Mock for NamedParameterJdbcTemplate, hashCode: <n>
1. namedParameterJdbcTemplate.query("query", my.package.MyClass$$Lambda$114/1274225913@3e134896);
我明显做错了什么吗?提前感谢您的任何帮助。
英文:
I'm creating a unit test for the below Java code which gets data from a database and, via a lambda, maps the data retrieved into a list:
List<Pair<String, String>> list = jdbcTemplate.query(MY_QUERY, (rs, rowNum) -> {
String code = rs.getString(1);
String name = rs.getString(2);
return new Pair<String, String>(code, name);
});
It's part of a Spring framework service class; the unit test is run via SpringJUnit4ClassRunner.
I've used Mockito to mock the jdbcTemplate object (of type NamedParameterJdbcTemplate).
I'm trying to mock the result of the jdbcTemplate. Looking at the method call, it looks like I need to mock this method in the NamedParameterJdbcTemplate class:
query(String sql, RowMapper<T> rowMapper)
I have tried this:
List<Pair<String, String>> pairList = ...;
Mockito.when(jdbcTemplate.query(Mockito.anyString(), Mockito.any(RowMapper.class))).thenReturn(pairList);
... but when I run the unit test, the "list" variable is always null after the line of code has been passed, as if the mock hasn't been triggered to return my value.
The Mockito object is definitely being injected into the class.
Printing the mock's invocactions displays this:
[Mockito] Interactions of: Mock for NamedParameterJdbcTemplate, hashCode: <n>
1. namedParameterJdbcTemplate.query("query", my.package.MyClass$$Lambda$114/1274225913@3e134896);
Is there anything I'm obviously doing wrong? Thanks in advance for any assistance.
答案1
得分: 0
尝试使用Mockito.any(Function.class)
Mockito.when(jdbcTemplate.query(Mockito.anyString(), Mockito.any(Function.class))).thenReturn(pairList);
英文:
try Mockito.any(Function.class)
Mockito.when(jdbcTemplate.query(Mockito.anyString(), Mockito.any(Function.class))).thenReturn(pairList);
答案2
得分: 0
我将模拟的配置移到了它被创建的位置:
@Bean(name = "jdbcTemplate")
public NamedParameterJdbcTemplate jdbcTemplate() {
NamedParameterJdbcTemplate jdbcTemplate = Mockito.mock(NamedParameterJdbcTemplate.class);
Pair<String, String> pair = new Pair<String, String>(CODE, NAME);
List<Pair<String, String>> pairList = new ArrayList<Pair<String, String>>();
pairList.add(pair);
Mockito.when(jdbcTemplate.query(Mockito.anyString(), Mockito.any(RowMapper.class))).thenReturn(pairList);
return jdbcTemplate;
}
现在它可以正常工作。
英文:
I moved the mock's configuration to where it's created:
@Bean(name = "jdbcTemplate")
public NamedParameterJdbcTemplate jdbcTemplate() {
NamedParameterJdbcTemplate jdbcTemplate = Mockito.mock(NamedParameterJdbcTemplate.class);
Pair<String, String> pair = new Pair<String, String>(CODE, NAME);
List<Pair<String, String>> pairList = new ArrayList<Pair<String, String>>();
pairList.add(pair);
Mockito.when(jdbcTemplate.query(Mockito.anyString(), Mockito.any(RowMapper.class))).thenReturn(pairList);
return jdbcTemplate;
}
It works now.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论