Тестовое приложение Grails терпит неудачу, в то время как индивидуальное тестовое приложение объединяет тестовые работы - PullRequest
0 голосов
/ 11 октября 2018

У меня есть приложение Grails 3.3.5 с несколькими юнит-тестами.Хотя я запускаю эти тесты по отдельности, они запускаются, как и ожидалось, но когда я запускаю общее тестовое приложение, тесты завершаются неудачно с этим сообщением:

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.grails.beans.ConstraintsEvaluator': Cannot resolve reference to bean 'grailsDomainClassMappingContext' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'grailsDatastore': Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.grails.datastore.mapping.simple.SimpleMapDatastore]: Constructor threw exception; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [java.util.Map<?, ?>]
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:359)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:648)
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:145)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1197)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1099)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
    at org.grails.testing.GrailsUnitTest$Trait$Helper.defineBeans(GrailsUnitTest.groovy:100)
    at org.grails.testing.gorm.spock.DataTestSetupSpecInterceptor.setupDataTestBeans(DataTestSetupSpecInterceptor.groovy:50)
    at org.grails.testing.gorm.spock.DataTestSetupSpecInterceptor.configureDataTest(DataTestSetupSpecInterceptor.groovy:85)
    at org.grails.testing.gorm.spock.DataTestSetupSpecInterceptor.intercept(DataTestSetupSpecInterceptor.groovy:43)
    at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:87)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:114)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:57)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:66)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
    at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:109)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:147)
    at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:129)
    at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
    at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:46)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'grailsDatastore': Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.grails.datastore.mapping.simple.SimpleMapDatastore]: Constructor threw exception; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [java.util.Map<?, ?>]
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:279)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1197)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1099)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:372)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1177)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1071)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351)
    ... 36 more
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.grails.datastore.mapping.simple.SimpleMapDatastore]: Constructor threw exception; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [java.util.Map<?, ?>]
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:154)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:122)
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:271)
    ... 54 more
Caused by: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [java.util.Map<?, ?>]
    at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:324)
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:206)
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:187)
    at org.springframework.core.env.AbstractPropertyResolver.convertValueIfNecessary(AbstractPropertyResolver.java:266)
    at org.springframework.core.env.PropertySourcesPropertyResolver.getProperty(PropertySourcesPropertyResolver.java:87)
    at org.springframework.core.env.PropertySourcesPropertyResolver.getProperty(PropertySourcesPropertyResolver.java:66)
    at org.springframework.core.env.AbstractPropertyResolver.getProperty(AbstractPropertyResolver.java:169)
    at org.springframework.core.env.AbstractEnvironment.getProperty(AbstractEnvironment.java:542)
    at org.grails.datastore.mapping.core.connections.AbstractConnectionSources.getConnectionSourceNames(AbstractConnectionSources.groovy:52)
    at org.grails.datastore.mapping.core.connections.InMemoryConnectionSources.<init>(InMemoryConnectionSources.groovy:24)
    at org.grails.datastore.mapping.core.connections.ConnectionSourcesInitializer.create(ConnectionSourcesInitializer.groovy:28)
    at org.grails.datastore.mapping.simple.SimpleMapDatastore.<init>(SimpleMapDatastore.java:117)
    at org.grails.datastore.mapping.simple.SimpleMapDatastore.<init>(SimpleMapDatastore.java:178)
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:142)
    ... 56 more

Вот один из модульных тестов, который работает, как и ожидалось, когда запускается индивидуально, ноне удается выполнить глобальный тест:

package my.package

import grails.testing.gorm.DomainUnitTest
import spock.lang.Specification

class CapituloSpec extends Specification implements DomainUnitTest<Capitulo> {

    void "test id cannot be null"() {
        when:
        domain.id = null

        then:
        !domain.validate(['id'])
        domain.errors['id'].code == 'nullable'
    }

    void "test titulo cannot be null or blank"() {
        when:
        domain.titulo = null

        then:
        !domain.validate(['titulo'])
        domain.errors['titulo'].code == 'nullable'

        when:
        domain.titulo = ''

        then:
        !domain.validate(['titulo'])
        domain.errors['titulo'].code == 'blank'
    }

    void "test titulo maxSize"() {
        when: "titulo is 101 characters length"
        domain.titulo = 'a' * 101

        then: "titulo validation fails"
        !domain.validate(['titulo'])
        domain.errors['titulo'].code == 'maxSize.exceeded'

        when: "titulo is 100 characters length"
        domain.titulo = 'a' * 100

        then: "titulo validation succeed"
        domain.validate(['titulo'])
    }

    void "test capitulo ok"() {
        when:
        domain.id = 1
        domain.titulo = "Test"

        then:
        domain.validate()
    }
}

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

РЕДАКТИРОВАТЬ: Я забыл упомянуть, что яЯ использую два источника данных , один по умолчанию для сохранения почти всех данных приложения, а другой для сохранения только 6 доменов, совместно используемых с другим приложением.

1 Ответ

0 голосов
/ 23 октября 2018

Наконец-то я нашел способ избежать ошибок и запустить все тесты вместе.Я должен сконфигурировать источник данных во всех тестах, используя закрытие doWithSpring.

Сначала я сделал Trait для настройки источника данных с использованием applicationContext и имени источника данных (если не указано, используйте источник данных «по умолчанию»):

package my.package

import groovy.transform.CompileStatic
import org.springframework.context.ConfigurableApplicationContext
import org.springframework.core.convert.support.ConfigurableConversionService
import org.springframework.core.convert.converter.Converter

@CompileStatic
trait MultiDatasourceTest {

    def configDatasource(ConfigurableApplicationContext applicationContext, String datasource = "default") {
        System.setProperty("grails.gorm.connections", datasource)

        ConfigurableConversionService conversionService = applicationContext.getEnvironment().getConversionService()
        conversionService.addConverter(new StringToMapConverter())
    }
}

class StringToMapConverter implements Converter<String, Map> {
    @Override
    Map convert(String source) {
        source.split(",").collectEntries({
            [(it):it]
        })
    }
}

Далее я должен добавить признак ко всем моим тестам и вызвать configDatasource с контекстом приложения и именем источника данных, если это не значение по умолчанию.

Источник данных по умолчанию :

package my.package

import grails.testing.gorm.DomainUnitTest
import org.springframework.context.ConfigurableApplicationContext
import spock.lang.Specification

class CapituloSpec extends Specification implements DomainUnitTest<Capitulo>, MultiDatasourceTest {

    @Override
    Closure doWithSpring() {
        return {
            configDatasource(application.mainContext as ConfigurableApplicationContext)
        }
    }

    void "test id cannot be null"() {
        when:
        domain.id = null

        then:
        !domain.validate(['id'])
        domain.errors['id'].code == 'nullable'
    }

    // More tests
}

Другой источник данных:

package my.package

import grails.testing.gorm.DomainUnitTest
import org.springframework.context.ConfigurableApplicationContext
import spock.lang.Specification

class DocumentoTeoSpec extends Specification implements DomainUnitTest<DocumentoTeo>, MultiDatasourceTest {

    @Override
    Closure doWithSpring() {
        return {
            configDatasource(application.mainContext as ConfigurableApplicationContext, "sede")
        }
    }

    void "test numeroExpediente cannot be null or blank"() {
        when:
        domain.numeroExpediente = null

        then:
        !domain.validate(['numeroExpediente'])
        domain.errors['numeroExpediente'].code == 'nullable'

        when:
        domain.numeroExpediente = ''

        then:
        !domain.validate(['numeroExpediente'])
        domain.errors['numeroExpediente'].code == 'blank'

        when: "numeroExpediente is 21 characters long"
        domain.numeroExpediente = 'a' * 21

        then: "numeroExpediente validation fails"
        !domain.validate(['numeroExpediente'])
        domain.errors['numeroExpediente'].code == 'maxSize.exceeded'

        when: "numeroExpediente is 20 characters long"
        domain.numeroExpediente = 'a' * 20

        then: "numeroExpediente validation succeed"
        domain.validate(['numeroExpediente'])
    }

    // More tests
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...