I'd like to test a Grails controller that is sending out emails using the grails Email plugin. I'm at a loss exactly how to mock the sendMail
closure in order for interactions to work. Here's my latest version of the test code:
def 'controller should send a multipart email'() {
given: 'a mocked mailService'
controller.mailService = Mock(grails.plugin.mail.MailService)
controller.mailService.sendMail(*_) >> Mock(org.springframework.mail.MailMessage)
when:
controller.sendNow()
then:
1* _.multipart(true)
}
The controller code looks something like what you'd expect, e.g.:
def mailService
def sendNow() {
mailService.sendMail {
multipart true
to '[email protected]'
from '[email protected]'
subject 'a subject'
body 'a body'
}
}
If I run this test, I get 0 invocations of my multipart
interaction instead of 1. The second line of the given:
block seems suspicious to me, but if I try to mock a Closure
instead of org.springframework.mail.MailMessage
my test crashes. I should also mention that the controller itself works as expected (it couldn't wait for me to figure out the unit tests first).
Edited
Aha, looking at the code with a fresh mind a few hours later, I can see why the above code does not work; in order for me to catch multipart
and other DSL calls, I would have to mock the closure itself, not the sendMail method (and I can't do that since the closure is defined inside the controller itself). What I probably can do is check the arguments to the sendMail
method to see everything necessary was passed into it.