Динамические методы Grails отсутствуют при выполнении интеграционных тестов
Я работаю над проектом с использованием Grails 2.5.4 и в настоящее время пытаюсь запустить некоторые интеграционные тесты, которые не выполняются. Я отладил проблему и обнаружил, что, по-видимому, некоторые динамические методы в тестируемых сервисах отсутствуют при запуске интеграционного теста (если вы запускаете его в контексте приложения, методы есть, и все работает). Это происходит во многих тестах, которые я пытаюсь запустить, я выбрал один в качестве примера, но у других, которые терпят неудачу, есть те же проблемы.
У меня есть этот класс домена
class Event {
...
static hasMany = [
bundles : Bundle
]
...
}
и метод обслуживания для тестирования:
@Transactional
class BundleService {
...
void assignEvent(Event event, List bundleIds) {
..
for (id in bundleIds) {
event.addToBundles(Bundle.get(id))
}
}
...
}
Итак, я запускаю этот тест спока
class BundleServiceIntegrationSpec extends Specification {
BundleService bundleService
EventService eventService
private BundleTestHelper bundleHelper = new BundleTestHelper()
...
void '04. Test deleteBundleAndAssets method'() {
when: 'a new Bundle is created'
Bundle bundle = bundleHelper.createBundle(project, 'Test Bundle')
and: 'a new Event is created'
Event event = eventService.create(project, 'Test Event')
and: 'the above Bundle is assigned to the Event'
bundleService.assignEvent(event, [bundle.id])
...
}
происходит сбой в строке moveEvent.addToBundles(Bundle.get(id)) BundleService со следующим исключением
groovy.lang.MissingMethodException: No signature of method:
net.domain.Event.addToBundles() is applicable for argument
types: (net.domain.Bundle) values: [Test Bundle]
Possible solutions: getBundles()
at net.service.BundleService.$tt__assignEvent(BundleService.groovy:101)
Проблема заключается в том, что метод addToBundles(), который Grails должен динамически добавлять в класс Event из-за набора "bundles" коллекции hasMany, не добавляется. Как я уже говорил, если вы запускаете приложение и используете этот сервис, метод есть, и все работает.
Я попытался изменить базовый класс теста (со Спецификации на IntegrationSpec), так как я верю, что именно здесь управляются динамические возможности, а также управление транзакциями и другие вещи для интеграционных тестов, но это не сработало.
Есть ли причина, по которой этот метод, который должен присутствовать в сервисе, отсутствует в контексте интеграционных тестов? Спасибо
2 ответа
@Szymon Stepniak Спасибо за ваш ответ и извините за поздний ответ. Я проверил то, что вы предложили, но это не сработало. Позже я прочитал, что grails.test.mixin.Mock
аннотация предназначена только для модульных тестов и не должна использоваться в интеграционных тестах. Это также верно для @TestFor
а также @TestMixin
аннотации (я читал об этом в этом посте).
Поэтому после этого коллега на работе предложил мне поискать аннотации такого рода в других тестах, полагая, что это может привести к некоторому загрязнению теста между тестами и после удаления @TestFor
аннотация в одном из тестов, которые ранее выполнялись как часть всего комплекта интеграционных тестов, провалившийся тест, который я опубликовал, начал работать. Самая странная вещь (приложение от компилятора не жалуется на это) - это тест на оскорбления (тот, с которого я удалил @TestFor
аннотация) проходила все зеленое, это даже не подвело!
Поэтому, если у кого-то есть подобная проблема, я предлагаю поискать подобные аннотации модульных тестов в любом месте всего комплекта интеграционных тестов и удалить их, потому что компилятор не будет жаловаться, но по моему опыту это может повлиять на другие тесты и может привести к очень странному поведению.
Вам не хватает grails.test.mixin.Mock
аннотации в вашем тестовом классе. В модульном тесте Grails этот миксин используется для генерации всех связанных с доменом методов для класса, чтобы вы могли правильно использовать этот домен в модульном тесте. Нечто подобное должно сработать:
@Mock([Event])
class BundleServiceIntegrationSpec extends Specification {
BundleService bundleService
EventService eventService
private BundleTestHelper bundleHelper = new BundleTestHelper()
...
void '04. Test deleteBundleAndAssets method'() {
when: 'a new Bundle is created'
Bundle bundle = bundleHelper.createBundle(project, 'Test Bundle')
and: 'a new Event is created'
Event event = eventService.create(project, 'Test Event')
and: 'the above Bundle is assigned to the Event'
bundleService.assignEvent(event, [bundle.id])
...
}
Подробнее о тестировании классов доменов можно узнать здесь: https://grails.github.io/grails2-doc/2.4.5/guide/testing.html