mailService.sendMail {
to email
subject title
text body
}
This is not simple with normal mocking tools. What you need is a simple Mock mechanism that records the method calls made via the DSL. The DSLMock class (shown at the end) can handle this. The test will look something like this:
@Testvoid testAlertLogging() { def mailDSLMock = DSLMock.mock(MailService, 'sendMail', []) service.mailService = new MailService() service.triggerAlert('dummy@abc.xyz')
// check email was sent to the right user with the right subject/body
assert mailDSLMock.result.contains([name: 'to', args: ['dummy@abc.xyz']]) def subjectMap = mailDSLMock.result.find() { it.name == 'subject' }
assert subjectMap.args[0] == 'Default Subject' def bodyMap = mailDSLMock.result.find() { it.name == 'text' } assert body.bodyMap.args[0].contains('alert')
}
The DSLMock will simply record the calls to the DSL and your test code must verify the correct calls were made.
The DSLMock class is:
class DSLMock { /**
* Creates a mock for the given clazz and method.
* @param clazz The class to add the mock to.
* @param method The method that starts the DSL.
* @param result The expected result of the DSL.
* @return The mock. */
static DSLMock mock(clazz, method, result) { def tester = new DSLMock() clazz.metaClass.static."${method}" = { Closure dsl -> dsl.delegate = tester dsl.resolveStrategy = Closure.DELEGATE_FIRST dsl() return result } return tester } /** * The list of method calls made to the mocked DSL and their arguments. */
def result = [] /**
* Used to record the method calls made to the mock.
* @param name The method name.
* @param args The arguments.
* @return */
def methodMissing(String name, args) { result << [name: name, args: args.toList()] }
}
(Sorry for the formatting of the code. I am still learning how to use the blog editor).


