在控制器中有一个动作:
def delete = {
withDomain {
it.delete()
flash.message = "${message(code: 'default.deleted.message', args: [message(code: 'chocolateBar.label', default: 'ChocolateBar'), it.name])}"
redirect action: 'list'
}
}
可以在开发中测试。在单元测试中,message(..)方法抛出异常(groovy.lang.MissingMethodException:没有方法签名:longtest.ChocolateBarController.message()适用于参数类型:(java.util .LinkedHashMap)值:[[code:chocolateBar.label,默认:ChocolateBar]]):
public void testDelete() {
controller.params.id = '3'
controller.delete()
assert 'list'==controller.redirectArgs.action
}
研究后,应在安装过程中调用 mockTagLib 方法。但是没有找到内置消息(..)的正确类名。请帮忙。
答案 0 :(得分:4)
我已经解决了单元控制器测试中的问题。像这样:
//This is inside Spock test
@Shared
ResourceBundleMessageSource messageSource = null
@Shared
Closure mockMessage = {Map map ->
return messageSource.getMessage((String)map.code, (Object[])map.args, Locale.default)
}
def setupSpec(){
URL url = new File('grails-app/i18n').toURI().toURL()
messageSource = new ResourceBundleMessageSource()
messageSource.bundleClassLoader = new URLClassLoader(url)
messageSource.basename = 'messages'
messageSource.setDefaultEncoding("utf-8")
}
def setup(){
controller.metaClass.message = mockMessage
}
此代码用于spock测试,但主要思路也可用于正常的grails测试
在运行阶段(不是测试),
在控制器类中调用“message”会导致调用ValidationTagLib类的“消息”,
但它们在单元测试阶段没有约束力
所以我对ValidationTagLib的“消息”做了几乎相同的逻辑,
并将它(名为“mockMessage”)绑定到controller.message
使用此代码,您可以在测试中的控制器类中正确执行“消息”。