在 Groovy 个单元测试中覆盖 JdbcTemplate 方法

Override JdbcTemplate method in Groovy unit tests

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

你好, 为 grails 服务 class 编写一些单元测试,我有一个关于包含对 jdbcTemplate.query(string sql, Object[] params, 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 的新手) 谢谢

尽管这应该可以通过地图强制转换实现,但正如您所尝试的那样,我建议为此使用 Spock Framework

Specification class,您重写以编写测试,它包含 MockStub 方法,因此您可以执行以下操作:

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

这甚至应该为您提供正确的错误消息,以便您可以更轻松地找出问题所在。

好的,所以我设法让它工作(我忘了,我在那个项目上坚持使用 grails 1.3.7,它将是 "upgraded later if we have time")

所以,使用 mockFor :

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

这行得通。如您所见,与我在问题中的示例不同,我 return ['dummy'] 作为列表,没有 'dummy' 作为字符串。我以为那是个错误,但没有,没有任何改变:/