Grails 在Groovy单元测试中重写JdbcTemplate方法

Grails 在Groovy单元测试中重写JdbcTemplate方法,grails,groovy,jdbctemplate,Grails,Groovy,Jdbctemplate,免责声明:我知道,集成测试正在进行中,我只需要测试jdbc查询之后会发生什么;) 嗨, 在为grails服务类编写单元测试时,我遇到了一个关于包含对jdbcTemplate.query(字符串sql、对象[]参数、RowMapper rm)调用的方法的小问题 为了测试查询之后会发生什么,我需要提供一个伪值。在以前的测试中,我能够使用以下命令覆盖queryForList: Service service = new Service() def jdbcTemplate = [queryForLis

免责声明:我知道,集成测试正在进行中,我只需要测试jdbc查询之后会发生什么;)

嗨, 在为grails服务类编写单元测试时,我遇到了一个关于包含对jdbcTemplate.query(字符串sql、对象[]参数、RowMapper rm)调用的方法的小问题

为了测试查询之后会发生什么,我需要提供一个伪值。在以前的测试中,我能够使用以下命令覆盖queryForList:

Service service = new Service()
def jdbcTemplate = [queryForList : {q, o -> return [1,2,3]}] as JdbcTemplate
service.setJdbcTemplate(jdbcTemplate);
没有任何问题。但是,对于查询方法,没有成功。与

def jdbcTemplate = [query : {q, o, rm -> 'dummy'}] as JdbcTemplate
def jdbcTemplate = [query : {String q, Object[] o, RowMapper rm -> 'dummy'}] as JdbcTemplate
def jdbcTemplate = [query : {String q, Object o, RowMapper rm -> 'dummy'}] as JdbcTemplate
都以失败告终

groovy.lang.MissingMethodException: No signature of method: 
JdbcTemplate_groovyProxy.query() is applicable for argument types: 
(java.lang.String, java.util.ArrayList, com.sun.proxy.$Proxy6) 
values: [select something from something where id = ? , [1], Service$_method_closure1@16aca316]
Possible solutions: query(java.lang.String, org.springframework.jdbc.core.ResultSetExtractor), 
query(java.lang.String, [Ljava.lang.Object;, org.springframework.jdbc.core.ResultSetExtractor), 
query(java.lang.String, org.springframework.jdbc.core.PreparedStatementSetter, 
org.springframework.jdbc.core.ResultSetExtractor), query(java.lang.String,
org.springframework.jdbc.core.ResultSetExtractor, [Ljava.lang.Object;), 
query(java.lang.String, org.springframework.jdbc.core.RowMapper), 
query(java.lang.String, [Ljava.lang.Object;, 
org.springframework.jdbc.core.RowMapper)
有什么提示吗?还是我在这里做了什么坏事?(我是groovy新手)
谢谢。

尽管这应该可以通过地图强制实现,但在您尝试时,我建议使用

Specification
类(您重写它来编写测试)包含
Mock
Stub
方法,因此您可以执行以下操作:

def mockJdbc = Mock( JdbcTemplate ) {
    query(_, _, _) >> 'DUMMY'
}

这甚至会给你正确的错误消息,这样你就可以更容易地找出错误所在。

好的,所以我设法让它正常工作(我忘了,我在那个项目上坚持使用grails 1.3.7,它将“稍后升级,如果我们有时间”)

因此,使用mockFor:

def jdbcTemplate = mockFor(JdbcTemplate.class)
jdbcTemplate.demand.query() {q, o, rm -> ['dummy']}
service.setJdbcTemplate(jdbcTemplate.createMock());

这就行了。正如您所注意到的,与问题中的示例不同,我将['dummy'作为列表返回,而不是将'dummy'作为字符串返回。我认为这是个错误,但没有,什么都没有改变://

谢谢你的指点,我会调查一下。我使用mockFor(见下文)成功地完成了测试,但仍然不知道为什么映射强制(感谢其名称)不起作用:/hmm,有趣的是:继续下一个方法,我需要再次模拟queryForList。所以我使用:jdbcTemplate.demand.queryForList(){q,o->[]},但它不起作用。在这里,只有地图强制(如问题中所述)起作用。有人知道为什么吗?