如何在 Groovy/Grails 中模拟静态闭包

How to mock static closures in Groovy/Grails

我正在尝试单元(而不是集成)测试一段我无法更改的遗留代码:

class Job {
 public boolean isStale(String param) {
     def status
     StatusObj.withTransaction {
        status = StatusObj.findByJobIdAndParam(getId(), param)
     }
     return status
 }
}

这是我尝试存根的尝试:

 def  () {
        setup:        
        GroovySpy(StatusObj, global: true)       
        StatusObj.withTransaction(_) >> StatusObj
        StatusObj.findByJobIdAndParam(_,_) >> 2


        when:
        def isStale = job.isStale("test")
        then:
        isStale == 2
    }

我不知道如何进入内部模拟

尝试这样的事情:

@Unroll
class JobSpec extends Specification {
    def "spec"() {
        when:
        GroovySpy(StatusObj, global: true)
        def job = new Job(id: "ID")
        def param = "test"
        1 * StatusObj.withTransaction(_) >> { Closure action ->
            action.call()
        }
        1 * StatusObj.findByJobIdAndParam(job.id, param) >> status

        then:
        job.isStale(param) == isStale

        where:
        status | isStale
        0      | false
        1      | true
        2      | true
    }
}

这里 action 是您来自 Job class 的 status = StatusObj.findByJobIdAndParam(getId(), param)。它的工作原理可以在 Spock 文档的 Computing Return Values and Performing Side Effects 部分找到。另外,请注意,我通过将 id 字段添加到 Job class 来使 Job.getId() 起作用。我不确定它是如何在你的代码中实现的

findByJobIdAndParam 需要 2 个参数:

status = StatusObj.findByJobIdAndParam(getId(), param)

您的存根需要 1 个参数:

StatusObj.findByJobIdAndParam(_) >> 2

尝试像这样更改存根:

StatusObj.findByJobIdAndParam(_, _) >> 2