Spock returns 模拟 JdbcTemplate 时为空列表
Spock returns empty list when mocking JdbcTemplate
我有一项服务 class,它使用 JdbcTemplate 执行使用产品 ID 和 return 匹配产品的搜索。
这是class
@RequiredArgsConstructor
@服务
public class 产品服务 {
private final QueryBuilderUtility queryBuilderUtility;
private final JdbcTemplate productJdbcTemplate;
public ProductService(@Qualifier("productJdbcTemplate") JdbcTemplate productJdbcTemplate, QueryBuilderUtility queryBuilderUtility) {
this.productJdbcTemplate = productJdbcTemplate;
this.queryBuilderUtility = queryBuilderUtility;
}
public List<Product> findProducts(List<Long> productCodes) {
String productQuery = queryBuilderUtility.buildSelectQuery(productCodes);
List<Product> products = productJdbcTemplate.query( productQuery, new ProductRowMapper(), productCodes.toArray());
return products;
}
这里是测试class:
class ProductServiceSpec extends Specification {
JdbcTemplate jdbcTemplate = Mock()
QueryBuilderUtility queryBuilderUtility = Mock()
ProductService productService
List<Long> productCodes = [33334L, 66754L, 56772L]
TestUtil testUtil = new TestUtil();
List<Product> products = testUtil.createProducts()
def setup(){
productService = new ProductService( jdbcTemplate, queryBuilderUtility)
}
def 'Find Products for product codes'(){
given:
1 * jdbcTemplate.query(_ as String, _ as ProductRowMapper, _ as Object []) >> products
when:
//1 * jdbcTemplate.query(_ as String, _ as ProductRowMapper, _ as Long []) >> products
assert products.size() == 3
List<Product> result = productService.findProducts(productCodes)
println "Result is ${result}" // empty list
then:
1 == 1
}
}
我尝试使用 jdbcTemplate 的存根来 return 类似这样的产品列表,但该列表是空的
List<Product> products = ...
JdbcTemplate jdbcTemplate = Stub()
jdbcTemplate.query(_ as String, _ as ProductRowMapper, _ as Long []) >> products
但是,当我调试时,它 return 是一个大小为 0 的产品列表,即使产品列表中有 3 个元素。这是预期的吗?如果是这样,是否意味着不可能在 Spock 中模拟或存根 JdbcTemplate?如果有人能帮助我解决这个问题,我将不胜感激。
我也试过了,还是不行;
JdbcTemplate template = Mock()
1 * template.query(_ as String, _ as ProductRowMapper, _ as Object[]) >> products
和
1 * template.query(_ as String, _ as ProductRowMapper, _ as Long[]) >> products
您将 QueryBuilderUtility
定义为模拟:
QueryBuilderUtility queryBuilderUtility = Mock()
即每个方法调用 returns null
。因此,您要么需要使用真正的查询构建器实用程序而不是模拟,要么确保对方法结果进行存根,例如
def 'Find Products for product codes'() {
given:
1 * jdbcTemplate.query(_ as String, _ as ProductRowMapper, _ as Object[]) >> products
queryBuilderUtility.buildSelectQuery(_) >> "my query"
expect:
productService.findProducts(productCodes).size() == 3
}
现在测试应该通过了。
顺便说一下:在这种简单的情况下,您似乎不需要 jdbcTemplate.query
的方法参数的任何值约束,但每个 _
,您也可以简单地写:
1 * jdbcTemplate.query(*_) >> products
更新:查看我的完整示例项目,其中包含我创建的几个虚拟 类 以使您的示例代码工作:
在 Groovy Web Console 中尝试。
我有一项服务 class,它使用 JdbcTemplate 执行使用产品 ID 和 return 匹配产品的搜索。
这是class
@RequiredArgsConstructor
@服务 public class 产品服务 {
private final QueryBuilderUtility queryBuilderUtility;
private final JdbcTemplate productJdbcTemplate;
public ProductService(@Qualifier("productJdbcTemplate") JdbcTemplate productJdbcTemplate, QueryBuilderUtility queryBuilderUtility) {
this.productJdbcTemplate = productJdbcTemplate;
this.queryBuilderUtility = queryBuilderUtility;
}
public List<Product> findProducts(List<Long> productCodes) {
String productQuery = queryBuilderUtility.buildSelectQuery(productCodes);
List<Product> products = productJdbcTemplate.query( productQuery, new ProductRowMapper(), productCodes.toArray());
return products;
}
这里是测试class:
class ProductServiceSpec extends Specification {
JdbcTemplate jdbcTemplate = Mock()
QueryBuilderUtility queryBuilderUtility = Mock()
ProductService productService
List<Long> productCodes = [33334L, 66754L, 56772L]
TestUtil testUtil = new TestUtil();
List<Product> products = testUtil.createProducts()
def setup(){
productService = new ProductService( jdbcTemplate, queryBuilderUtility)
}
def 'Find Products for product codes'(){
given:
1 * jdbcTemplate.query(_ as String, _ as ProductRowMapper, _ as Object []) >> products
when:
//1 * jdbcTemplate.query(_ as String, _ as ProductRowMapper, _ as Long []) >> products
assert products.size() == 3
List<Product> result = productService.findProducts(productCodes)
println "Result is ${result}" // empty list
then:
1 == 1
}
}
我尝试使用 jdbcTemplate 的存根来 return 类似这样的产品列表,但该列表是空的
List<Product> products = ...
JdbcTemplate jdbcTemplate = Stub()
jdbcTemplate.query(_ as String, _ as ProductRowMapper, _ as Long []) >> products
但是,当我调试时,它 return 是一个大小为 0 的产品列表,即使产品列表中有 3 个元素。这是预期的吗?如果是这样,是否意味着不可能在 Spock 中模拟或存根 JdbcTemplate?如果有人能帮助我解决这个问题,我将不胜感激。
我也试过了,还是不行;
JdbcTemplate template = Mock()
1 * template.query(_ as String, _ as ProductRowMapper, _ as Object[]) >> products
和
1 * template.query(_ as String, _ as ProductRowMapper, _ as Long[]) >> products
您将 QueryBuilderUtility
定义为模拟:
QueryBuilderUtility queryBuilderUtility = Mock()
即每个方法调用 returns null
。因此,您要么需要使用真正的查询构建器实用程序而不是模拟,要么确保对方法结果进行存根,例如
def 'Find Products for product codes'() {
given:
1 * jdbcTemplate.query(_ as String, _ as ProductRowMapper, _ as Object[]) >> products
queryBuilderUtility.buildSelectQuery(_) >> "my query"
expect:
productService.findProducts(productCodes).size() == 3
}
现在测试应该通过了。
顺便说一下:在这种简单的情况下,您似乎不需要 jdbcTemplate.query
的方法参数的任何值约束,但每个 _
,您也可以简单地写:
1 * jdbcTemplate.query(*_) >> products
更新:查看我的完整示例项目,其中包含我创建的几个虚拟 类 以使您的示例代码工作:
在 Groovy Web Console 中尝试。