Динамические методы 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 из-за коллекции hasMany "bundles", не добавляется. Как я уже упоминал, если вы запустите приложение и воспользуетесь этой службой, метод будет готов, и все будет работать.

Я попытался изменить базовый класс теста (с Specification на IntegrationSpec), так как я считаю, что именно здесь динамический возможности, а также управление транзакциями и другие вещи для интеграционных тестов управляются, но это не сработало.

Есть ли причина, по которой этот метод, который должен быть в сервисе, отсутствует в контексте интеграционных тестов? Спасибо


person Esteban Cantu    schedule 25.09.2018    source источник


Ответы (2)


В вашем тестовом классе отсутствует аннотация 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#unitTestingDomains

person Szymon Stepniak    schedule 25.09.2018

@Szymon Stepniak Спасибо за ответ и извините за поздний ответ. Я проверил то, что вы предложили, но это не сработало. Позже я прочитал, что аннотация grails.test.mixin.Mock предназначена только для модульных тестов и не должна использоваться в интеграционных тестах. Это также верно для аннотаций @TestFor и @TestMixin (я читал об этом в этот пост).
Итак, после этого коллега на работе предложил мне поискать такого рода аннотации в других тестах, думая, что, возможно, это может привести к какому-то тестовому загрязнению между тестами, и после удаления @TestFor в одном из тестов, которые выполнялись ранее как часть всего комплекта интеграционных тестов, опубликованный мной неудачный тест начал работать. Самое странное (кроме того, что компилятор на это не жалуется) заключается в том, что оскорбительный тест (тот, из которого я убрал аннотацию @TestFor) прошел весь зеленый цвет, он даже не провалился!
Так что, если у кого-то есть подобное проблема Я предлагаю искать такого рода аннотации модульных тестов где-нибудь во всем наборе интеграционных тестов и удалять их, потому что компилятор не будет жаловаться, но по моему опыту это может повлиять на другие тесты и может привести к очень странному поведению.

person Esteban Cantu    schedule 23.10.2018