Правильный способ метапрограммы в Grails, чтобы он был доступен в модульных тестах - PullRequest
4 голосов
/ 16 января 2012

Я могу добавить метод к типу Java Integer в Groovy со строками:

ExpandoMetaClass.EnableGlobally()
Integer.metaClass.gimmeAP = {->return 'p'}

Я не знаю, зачем мне это нужно, но это понятно. Теперь я могу звонить целым числам и возвращать «p». Теперь допустим, что я хочу это в приложении Grails, чтобы я мог совершать звонки в доменных объектах. Конкретная проблема, с которой я сталкиваюсь, заключается в том, что когда я помещаю эти строки метапрограммирования в загрузчик, все метапрограммирование не доступно в модульных тестах, поэтому мои модульные тесты завершаются с ошибками типа «Нет метода gimmeAP для java.lang.Integer». или что-то в этом роде.

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

Я видел этот вопрос: Grails - создание глобально доступных методов и программирование метаклассов и, похоже, моя строка ExpandoMetaClass.EnableGlobally() может решить его проблему, но я правильно ее использую?

1 Ответ

2 голосов
/ 07 февраля 2012

Bootstrap не выполняется для модульных тестов. Я лично предпочел бы создать метод mockFoo, который выполняет вышеописанное метапрограммирование, а затем я вызову mockFoo из тестовой установки. Также посмотрите на GrailsUnitTestCase.registerMetaClass. Зарегистрируйте метакласс, прежде чем добавлять фиктивные методы, чтобы они не протекали в других тестах.

    registerMetaClass(SecurityUtils)
    SecurityUtils.metaClass.'static'.getSubject = { ->
        return [logout: { return true } ] as Subject
    }

Я знаю, что вы хотите сделать свои динамические методы доступными для всех юнит-тестов, но нет ничего, кроме начальной загрузки для юнит-тестов. Так что вы должны делать это в каждом тесте.

Вы можете создать MockHelper со статическим методом и вызывать его из набора тестов.

...