Как смоделировать / заглушить вызовы сообщения taglib в контроллере Grails - PullRequest
6 голосов
/ 06 января 2010

У меня есть контроллер 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]]

Кто-нибудь знает лучший способ обойти эту проблему в модульном тесте? В идеале я хотел бы сделать утверждения в сообщении, но сейчас я был бы рад, если бы тест только что запустился!

Спасибо

Ответы [ 4 ]

8 голосов
/ 06 января 2010

Вы можете динамически добавить отсутствующий метод в ваш тест. Не уверен, что это на 100% правильно, но что-то вроде ....

void testPasswordResetInvalidTokenRedirect() {
    controller.metaClass.message = { LinkedHashMap arg1 -> return 'test message output'}
    controller.passwordReset()
    assert...
}
5 голосов
/ 06 января 2010

Вы можете подключить его, используя метакласс, что-то вроде:

void testPasswordResetInvalidTokenRedirect() {

   TokenControllerTests.metaClass.message = { Map p -> return "foo" }
   controller.passwordReset()
   assert...
}

Это всегда возвращает одно и то же сообщение (при условии, что вам не важно, какое значение), но вы можете добавить логику, если хотите, то есть проверить значение «кода» и вернуть соответствующую строку.

2 голосов
/ 07 января 2010

Помимо попыток ответить на приведенные выше вопросы, я решил разрешить сообщение в gsp и таким образом удалить зависимость от тега lib.

Мой код для класса теперь выглядит так:

if (!isValidToken(token, params)) {
    flash.message = "forgotPassword.reset.invalidToken"

А в gsp у меня есть:

<g:message code="${flash.message}" args="${flash.args}" default="${flash.defaultMsg}"/>

Решение, вдохновленное документами Грааля

Конечно, ответы Дерека и Берта работают для всех библиотек тегов, поэтому есть более общие решения.

0 голосов
/ 24 апреля 2010

Я думаю, что это лучший способ ...

Поместите это в тест непосредственно перед вызовом метода контроллера:

controller.metaClass.message = { LinkedHashMap key -> assertEquals 'please.create.business', key.code}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...