У меня есть контроллер Grails, который полагается на сообщение taglib для разрешения сообщения i18n:
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]
}
}
Я записал модульный тест на контроллер:
class TokenControllerTests extends ControllerUnitTestCase {
void testPasswordResetInvalidTokenRedirect() {
controller.passwordReset()
assert...
}
}
Начиная с сообщения taglib называют в контроллере, я получаю MissingMethodException:
groovy.lang.MissingMethodException: No signature of method: TokenController.message() is applicable for argument types: (java.util.LinkedHashMap) values: [[code:forgotPassword.reset.invalidToken]]
Кто-либо знает лучший способ обойти эту проблему в модульном тесте? Идеально я хотел бы выполнить утверждения на сообщении, но прямо сейчас я был бы счастлив, если бы тест просто работал!
Спасибо
Попробовав вышеприведенные ответы, я решил разрешить сообщение в gsp и таким образом удалить зависимость от тэга lib все вместе.
Мой код для класса теперь выглядит так:
if (!isValidToken(token, params)) {
flash.message = "forgotPassword.reset.invalidToken"
И в gsp у меня есть:
<g:message code="${flash.message}" args="${flash.args}" default="${flash.defaultMsg}"/>
Решение, вдохновленное Grails docs
Конечно ответы Дерека и Берта работают для всех lib-тегов, так что это более общее решение.
.Вы можете динамически добавлять отсутствующий метод в вашем тесте. Не уверен, 100% ли это правильно, но что-то вроде....
void testPasswordResetInvalidTokenRedirect() {
controller.metaClass.message = { LinkedHashMap arg1 -> return 'test message output'}
controller.passwordReset()
assert...
}
Вы можете подключить его с помощью Metaclass, что-то вроде:
void testPasswordResetInvalidTokenRedirect() {
TokenControllerTests.metaClass.message = { Map p -> return "foo" }
controller.passwordReset()
assert...
}
Это возвращает одно и то же сообщение всегда (предполагая, что вам на самом деле все равно, что это за значение), но вы можете добавить логику, если хотите, т.е. проверить значение 'code' и вернуть соответствующую строку.
.Я думаю, что это лучший способ ...
Протестируйте это непосредственно перед вызовом метода контроллера:
controller.metaClass.message = { LinkedHashMap key -> assertEquals 'please.create.business', key.code}