Тестирование библиотек тегов Grails, которые вызывают другие библиотеки тегов

Скажем, у меня есть две библиотеки тегов: Foo, которая делает что-то конкретное для определенной части моего приложения, и Util, которая является общей для всего приложения. Я хочу сделать что-то вроде этого:

class UtilTagLib {
    def utilTag = { attrs -> 
        ...
    }
}

class FooTagLib {
    def fooTag = {
        ...
        out << g.utilTag(att1: "att1", att2: "att2")
        ...
    }
}

Однако, когда я делаю это и пытаюсь запустить модульный тест для fooTag(), я получаю:

groovy.lang.MissingMethodException: нет подписи метода: org.codehaus.groovy.grails.web.pages.GroovyPage.utilTag() применимо для типов аргументов: (java.util.LinkedHashMap) значения: [[att1:att1, att2 :att2]]

Я попытался дать UtilTagLib собственное пространство имен.

static namespace = "util"

и изменение вызова на

out << util.utilTag(...)

но это меня просто заводит

groovy.lang.MissingPropertyException: такого свойства нет: util для класса: org.example.FooTagLib

Возможно, также следует отметить: в журнале я вижу:

ПРЕДУПРЕЖДЕНИЕ. Компонент с именем «groovyPagesUriService» отсутствует.

Очевидно, что UtilTagLib не создается и не внедряется правильно. Как я могу это исправить?


person David Moles    schedule 28.06.2012    source источник


Ответы (2)


Решение: добавить вызов

mockTagLib UtilTagLib

к методу setUp() (или @Before) тестового примера. Это метод на GroovyPageUnitTestMixin, который несколько парадоксальным образом создает экземпляр указанной библиотеки тегов — настоящей, а не макета — и связывает ее с контекстом приложения Grails. Он используется внутри для настройки фактической тестируемой библиотеки тегов (в данном случае FooTagLib), но также работает для настройки дополнительных библиотек тегов соавторов.

Обратите внимание, что это не идеально, поскольку делает его скорее интеграционным тестом, чем чистым модульным тестом — в идеале мы были бы использовать макет UtilTagLib и просто тестировать взаимодействие.

person David Moles    schedule 02.07.2012

Одним из подходов может быть рефакторинг строки:

out << g.utilTag(att1: "att1", att2: "att2")

в свой собственный метод, скажем, "renderUtilTag(...)", затем смоделируйте его в модульном тесте, например:

FooTagLib.metaClass.renderUtilTag = { /* something */ }

Таким образом, вы тестируете функциональность FooTagLib только в модульном тесте, без зависимости от UtilTagLib.

person Jon Burgess    schedule 28.06.2012
comment
Я полагаю, но дело в том, чтобы убедиться, что FooTagLib правильно взаимодействует с UtilTagLib. - person David Moles; 28.06.2012