如何在使用Mail插件的Grails服务中集成测试电子邮件正文

时间:2012-01-16 17:54:44

标签: grails mocking integration-testing

我正在尝试为Grails服务编写集成测试,其中包括通过优秀的Mail Plugin发送电子邮件。我可以通过配置禁用实际的电子邮件发送,这很好,但我想验证参数是否正确正确呈现正文,或者至少在我预期时调用了该方法。根据文档,必须提供身体GSP的完整路径。

作为我测试的一部分,我想做类似的事情 - 有没有办法在发送后以编程方式访问电子邮件正文和其他参数?

sendMail {
  to myemailparams.to
  subject myemailparams.subject
  body( view:"/emailviews/someemailview", 
      model:[contentparam: myemailparams.somecontentvalue)
}

//verify correct sending to and subject parameters, and that body contains correct contentvalue
//or at least that the method has been called (Mock it out?)

注意我意识到我可以将电子邮件正文渲染的测试封装到一个不涉及邮件插件的单独的独立测试中。但是,这种集成测试的目的是确保在调用服务方法时正确地发生许多事情,包括电子邮件发送。我甚至会对描述如何模拟服务的答案感到满意,并且会在预期时调用验证“sendMail”的检查。

2 个答案:

答案 0 :(得分:4)

您可以使用metaClass覆盖sendMail方法,然后进行一些检查以确保调用sendMail:

void testSendMail() {
    MyClass myClass = new MyClass()
    def sendMailCalled = false
    myClass.metaClass.sendMail = { Closure c->
       sendMailCalled = true
    }

    myClass.functionThatCallsSendMail()
    assert sendMailCalled
}

答案 1 :(得分:2)

以下是我如何断言发送给MailService的内容的示例:

def setup(){
    mailParams = [:]
    mockMailService.ignore.sendMail{ callable ->
        messageBuilder = new MailMessageBuilder(null, new ConfigObject())
        messageBuilder.metaClass.body = { Map params ->
            mailParams.body = params
        }
        messageBuilder.metaClass.async = { Boolean param ->
            mailParams.async = param
        }
        messageBuilder.metaClass.to = { String param ->
            mailParams.to = param
        }
        messageBuilder.metaClass.subject = { String param ->
            mailParams.subject = param
        }
        callable.delegate = messageBuilder
        callable.resolveStrategy = Closure.DELEGATE_FIRST
        callable.call()
    }
    service.mailService = mockMailService.proxyInstance()
}

然后,在我的测试中,在执​​行发送邮件的方法之后,我断言这种方式(断言的Spock语法):

    then:
        mailParams.to == 'test@test.com'
        mailParams.async == true
        mailParams.subject == 'fnuser.billingEmail.subject{}en'
        mailParams.body.view == '/mailtemplates/setBillingEmail'
        mailParams.body.model.destinationUrl == "myDestinationUrl"
        mailParams.body.model.logoUrl == 'myUrl/templatelogo.png'
        mailParams.body.model.locale == Locale.ENGLISH