unit-testing - 尝试在单元测试中验证 Groovy 闭包

标签 unit-testing groovy spock

我正在尝试验证名为 CUTService 的类中的这个 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),并用这个委托(delegate)调用你的闭包。您的闭包实际上执行为:

delegate.to('hey@example.com')
delegate.from('hey@example.com')
delegate.subject('Stuff')
delegate.body('More stuff')

要测试这个闭包,您应该创建一个模拟,将闭包的委托(delegate)配置到这个模拟,调用闭包,并验证模拟期望。

因为这个任务不是很简单,所以最好重用邮件插件并创建他自己的邮件构建器:

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")

关于unit-testing - 尝试在单元测试中验证 Groovy 闭包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35509025/

相关文章:

grails - 为什么 map.collectEntries() 不适用于此数据 [[Name :sub, Value:23234]] - Groovy

java - 用 Spock 模拟 "blocking"方法调用?

unit-testing - Node.js 中的自动化 Web UI 测试

java - 单元测试 OSGi 组件

groovy - 从字符串中获取 IP 地址(Groovy)

mysql - 在groovy中调用mysql存储过程

javascript - 模拟 firebase 模块后模拟 firebase auth 方法的实现

c# - 如何在 NSubstitute 中伪造一个对象并忽略其方法的内部实现?

groovy - jenkins 扩展参数插件 groovy 脚本

java - Lombok 和斯波克 : @RequiredArgsConstructor doesn't hide default no-args constructor for a field with a type of interface