I've got a Grails controller which relies on the message taglib to resolve an i18n message:
class TokenController {
def passwordReset = {
def token = DatedToken.findById(params.id);
if (!isValidToken(token, params)) {
flash.message = message(code: "forgotPassword.reset.invalidToken")
redirect controller: 'forgotPassword', action: 'index'
return
}
render view:'/forgotPassword/reset', model: [token: token.token]
}
}
I've written a unit test for the controller:
class TokenControllerTests extends ControllerUnitTestCase {
void testPasswordResetInvalidTokenRedirect() {
controller.passwordReset()
assert...
}
}
Since the message taglib is called in the controller I get a MissingMethodException:
groovy.lang.MissingMethodException: No signature of method: TokenController.message() is applicable for argument types: (java.util.LinkedHashMap) values: [[code:forgotPassword.reset.invalidToken]]
Does anyone know the best way to get around this issue in a unit test? Ideally I would like to perform assertions on the message but right now I'd be happy if the test just ran!
Thanks
You could dynamically add the missing method in your test. Not sure if this is 100% correct but something like....
void testPasswordResetInvalidTokenRedirect() {
controller.metaClass.message = { LinkedHashMap arg1 -> return 'test message output'}
controller.passwordReset()
assert...
}
You can wire it up using the Metaclass, something like:
void testPasswordResetInvalidTokenRedirect() {
TokenControllerTests.metaClass.message = { Map p -> return "foo" }
controller.passwordReset()
assert...
}
This returns the same message always (assuming you don't really care what the value is) but you can add logic if you want, i.e. check the value of 'code' and return a corresponding string.
As well as trying the above answers, I decided to resolve the message in the gsp and so remove the dependency on the tag lib all together.
My code for the class now looks like:
if (!isValidToken(token, params)) {
flash.message = "forgotPassword.reset.invalidToken"
And in the gsp I have:
<g:message code="${flash.message}" args="${flash.args}" default="${flash.defaultMsg}"/>
A solution inspired by the grails docs
Of course Derek and Burt's answers work for all tag libs so are more general solutions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With