我有一个Grails服务,可以执行where
这样的查询:
List<Car> search(Long makeId = null) {
Car.where {
join("make")
if(makeId) {
make.id == makeId
}
}.findAll()
}
我正试图用Spock对它进行单元测试:
def setup() {
GroovyMock(Car, global: true)
}
void "test search"() {
when:
service.search()
then:
1 * Car.where {}
}
但是,我似乎无法找到测试闭包内容的方法。
我可以通过验证1 * Car.where(_)
来通过测试,但是如何对闭包的内容进行断言,即调用了join
并且make.id
约束是仅在需要时指定?
答案 0 :(得分:0)
您可以将闭包的委托设置为DetachedCriteria模拟,以对其进行断言。 DetachedCriteria是gorm中用于构建查询的主类。
示例:
given: 'Mocking DetachedCriteria'
DetachedCriteria detachedCriteriaMock = Mock(DetachedCriteria)
and: 'Just to avoid nullPointerException when findAll() call happens on service'
1 * detachedCriteriaMock.iterator() >> [].listIterator()
when:
service.search(1L)
then:
// Capture the argument
1 * Car.where(_) >> { args ->
args[0].delegate = detachedCriteriaMock
args[0].call()
return detachedCriteriaMock
}
// Join is a method on detached criteria
1 * detachedCriteriaMock.join('make')
// Make is an association, so detachedCriteria uses the methodMissing to find the property.
// In this case, we call the closure setting the delegate to the mock
1 * detachedCriteriaMock.methodMissing('make', _) >> { args ->
// args[1] is the list of arguments.
// args[1][0] is the closure itself passed to detachedCriteria
args[1][0].delegate = detachedCriteriaMock
args[1][0].call()
}
// If id is passed, it must compare (eq method) with value 1
1 * detachedCriteriaMock.eq('id', 1L)