Unit testing 单元测试void方法:验证参数

Unit testing 单元测试void方法:验证参数,unit-testing,grails,groovy,spock,Unit Testing,Grails,Groovy,Spock,我正在为我的程序创建一个单元测试。我有一个void方法,它接受五个参数,然后将这些参数转换为一个闭包,并将其传递给另一个服务,以转换为电子邮件并发送。我唯一关心的是这封电子邮件的正文,它存储在传递到此函数的一个参数中。是否可以在不改变程序设计的情况下验证此参数 我已经考虑过使用Spock风格的模拟,但我无法确定是否可以在经过规范测试的类中实际模拟/剔除方法,或者是否只能模拟依赖项 一个简化的例子 值显示为空。有什么想法吗?你可以嘲笑你的服务 这是一个非常简单的脚本,它模拟outsideServi

我正在为我的程序创建一个单元测试。我有一个void方法,它接受五个参数,然后将这些参数转换为一个闭包,并将其传递给另一个服务,以转换为电子邮件并发送。我唯一关心的是这封电子邮件的正文,它存储在传递到此函数的一个参数中。是否可以在不改变程序设计的情况下验证此参数

我已经考虑过使用Spock风格的模拟,但我无法确定是否可以在经过规范测试的类中实际模拟/剔除方法,或者是否只能模拟依赖项

一个简化的例子
值显示为空。有什么想法吗?

你可以嘲笑你的服务

这是一个非常简单的脚本,它模拟
outsideService
,将
html
方法中接收到的值存储在脚本变量中。您应该使用Spock/JUnit/YouNameIt使其整洁

class MyTestService
{
    def outsideService
    private void sendEmail (source, String subj, String body, List to, List attachments){
       outsideService.sendMail{
           subject subj
           html "<body>$body</body>"
       }
   }
}


myTest = new MyTestService()

def body
myTest.outsideService = [sendMail: { closure ->
  closure.delegate = new Expando(
    subject: { }, //don't care
    html: { body = it }
  )
  closure()
}]

myTest.sendEmail(null, 'my subject', 'my email body', null, null) 
assert '<body>my email body</body>' == body
类MyTestService
{
def外部服务
私有void sendmail(源、字符串主题、字符串正文、列表收件人、列表附件){
outsideService.sendMail{
主语主语
html“$body”
}
}
}
myTest=新的MyTestService()
def主体
myTest.outsideService=[sendMail:{closure->
closure.delegate=newexpando(
主题:{},//不在乎
html:{body=it}
)
闭包()
}]
myTest.sendEmail(空,'我的主题','我的邮件正文',空,空)
断言“我的电子邮件正文”==正文

我使用spock样式的模拟更新了我的问题,我没有得到正确的输出值(在您的示例中为body)。您的代码工作正常,但我不确定我的代码在哪里丢失了功能。使用元类更改了功能。具体实施。你的答案适用于我的测试用例,所以你的答案是正确的。不确定为什么我的示例没有转化为工作代码。
   //def params, request, filling in all necessary values

   def value
   def mailServiceMock = Mock(MailService)
   mailServiceMock.sendMail(*_) >> {closure ->
        closure.delegate = new Expando(
            multipart:{},
            from: {},
            subject: {},
            html: {value = it}
            bcc: {}
            )
        closure()
   }
   //inform service of mock
   service.mailService = mailServiceMock

   when:
       service.send(params, request)
   then:
   println("value = $value")
   1 * mailServiceMock.sendMail(*_) // this should fail, since this should be called twice, but one thing at a time.
   value.contains(params.body)

   }
class MyTestService
{
    def outsideService
    private void sendEmail (source, String subj, String body, List to, List attachments){
       outsideService.sendMail{
           subject subj
           html "<body>$body</body>"
       }
   }
}


myTest = new MyTestService()

def body
myTest.outsideService = [sendMail: { closure ->
  closure.delegate = new Expando(
    subject: { }, //don't care
    html: { body = it }
  )
  closure()
}]

myTest.sendEmail(null, 'my subject', 'my email body', null, null) 
assert '<body>my email body</body>' == body