尝试在单元测试中验证 Groovy 闭包
Trying to validate Groovy closure in a unit test
我正在尝试验证名为 CUTService 的 class 中的这个 groovy 闭包是否具有正确的值:
mailService.sendMail {
to 'hey@example.com'
from 'hey@example.com'
subject 'Stuff'
body 'More stuff'
}
我看过 https://github.com/craigatk/spock-mock-cheatsheet/raw/master/spock-mock-cheatsheet.pdf,但他的语法产生错误:
1 * mailService.sendMail({ Closure c -> c.to == 'hey@example.com'})
groovy.lang.MissingPropertyException: No such property: to for class: com...CUTService
我查看了 Is there any way to do mock argument capturing in Spock 并尝试了这个:
1 * mailService.sendMail({closure -> captured = closure })
assertEquals 'hey@example.com', captured.to
产生:
groovy.lang.MissingPropertyException: No such property: to for class: com...CUTService
我也试过这个:
1 * mailService.sendMail({captured instanceof Closure })
assertEquals 'hey@example.com', captured.to
产生:
Too few invocations for:
1 * mailService.sendMail({captured instanceof Closure }) (0 invocations)
...
Unmatched invocations (ordered by similarity):
1 * mailService.sendMail(com...CUTService$_theMethod_closure5@21a4c83b)
我需要做什么才能让它正常工作?
当你写:
mailService.sendMail {
to 'hey@example.com'
from 'hey@example.com'
subject 'Stuff'
body 'More stuff'
}
实际上,您正在执行方法 sendMail
,并带有闭包 c。 sendMail 创建一个委托,并用这个委托调用你的闭包。您的闭包实际上执行为:
delegate.to('hey@example.com')
delegate.from('hey@example.com')
delegate.subject('Stuff')
delegate.body('More stuff')
要测试这个闭包,您应该创建一个模拟,将闭包的委托配置到这个模拟,调用闭包,并验证模拟期望。
因为这个任务不是很简单,所以最好重用邮件插件并创建自己的邮件生成器:
given:
def messageBuilder = Mock(MailMessageBuilder)
when:
// calling a service
then:
1 * sendMail(_) >> { Closure callable ->
callable.delegate = messageBuilder
callable.resolveStrategy = Closure.DELEGATE_FIRST
callable.call(messageBuilder)
}
1 * messageBuilder.to("hey@example.com")
1 * messageBuilder.from("hey@example.com")
我正在尝试验证名为 CUTService 的 class 中的这个 groovy 闭包是否具有正确的值:
mailService.sendMail {
to 'hey@example.com'
from 'hey@example.com'
subject 'Stuff'
body 'More stuff'
}
我看过 https://github.com/craigatk/spock-mock-cheatsheet/raw/master/spock-mock-cheatsheet.pdf,但他的语法产生错误:
1 * mailService.sendMail({ Closure c -> c.to == 'hey@example.com'})
groovy.lang.MissingPropertyException: No such property: to for class: com...CUTService
我查看了 Is there any way to do mock argument capturing in Spock 并尝试了这个:
1 * mailService.sendMail({closure -> captured = closure })
assertEquals 'hey@example.com', captured.to
产生:
groovy.lang.MissingPropertyException: No such property: to for class: com...CUTService
我也试过这个:
1 * mailService.sendMail({captured instanceof Closure })
assertEquals 'hey@example.com', captured.to
产生:
Too few invocations for:
1 * mailService.sendMail({captured instanceof Closure }) (0 invocations)
...
Unmatched invocations (ordered by similarity):
1 * mailService.sendMail(com...CUTService$_theMethod_closure5@21a4c83b)
我需要做什么才能让它正常工作?
当你写:
mailService.sendMail {
to 'hey@example.com'
from 'hey@example.com'
subject 'Stuff'
body 'More stuff'
}
实际上,您正在执行方法 sendMail
,并带有闭包 c。 sendMail 创建一个委托,并用这个委托调用你的闭包。您的闭包实际上执行为:
delegate.to('hey@example.com')
delegate.from('hey@example.com')
delegate.subject('Stuff')
delegate.body('More stuff')
要测试这个闭包,您应该创建一个模拟,将闭包的委托配置到这个模拟,调用闭包,并验证模拟期望。
因为这个任务不是很简单,所以最好重用邮件插件并创建自己的邮件生成器:
given:
def messageBuilder = Mock(MailMessageBuilder)
when:
// calling a service
then:
1 * sendMail(_) >> { Closure callable ->
callable.delegate = messageBuilder
callable.resolveStrategy = Closure.DELEGATE_FIRST
callable.call(messageBuilder)
}
1 * messageBuilder.to("hey@example.com")
1 * messageBuilder.from("hey@example.com")