【问题标题】:MongoDB plugin - how to make it to not create a datasource during testing?MongoDB 插件 - 如何使其在测试期间不创建数据源?
【发布时间】:2015-09-26 15:39:34
【问题描述】:

我正在使用 Grails 2.3.8 和 MongoDB 开展一个项目。在我的项目中,我将MongoDB GORM plugin 和hibernate 一起包含在内,以简化数据库连接:

BuildConfig.groovy

// default config stuff here

grails.project.dependency.resolution = {
   ...

   plugins {
       ...
       compile ":mongodb:3.0.3"
       runtime ":hibernate:3.6.10.4"
    }
}

DataSource.groovy

environments {

    development {
        grails {
            mongo {
                host = "localhost"
                port = 27017
                databaseName = "myDB"
                // runs without --auth option needs no authentication
            }
        }
    }

    production {
        grails {
            mongo {
                databaseName = "myDB"
                username = "user"
                password = "*****"
                replicaSet = [
                        "master-host:port",
                        "slave1-host:port",
                        "slave2-host:port"
                ]
            }
        }
    }
}

如果我在本地机器(开发)或预生产服务器上运行我的应用程序,这会很好。

我的问题是我为我的控制器创建了一个集成测试,其中模拟了服务,根本不需要建立数据库连接。当我像这样运行测试时:

grails test test-app --debug-fork --stacktrace --verbose -integration

环境已正确设置为“测试”,但出现此异常:

Error Fatal error running tests: Error creating bean with name 'mongoTransactionManager': Cannot resolve reference to bean 'mongoDatastore' while setting bean property 'datastore'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoDatastore': FactoryBean threw exception on object creation; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: Timed out while waiting for a server that matches AnyServerSelector{} after 10000 ms; nested exception is com.mongodb.MongoTimeoutException: Timed out while waiting for a server that matches AnyServerSelector{} after 10000 ms
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoTransactionManager': Cannot resolve reference to bean 'mongoDatastore' while setting bean property 'datastore'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoDatastore': FactoryBean threw exception on object creation; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: Timed out while waiting for a server that matches AnyServerSelector{} after 10000 ms; nested exception is com.mongodb.MongoTimeoutException: Timed out while waiting for a server that matches AnyServerSelector{} after 10000 ms
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:336)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1456)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1197)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.codehaus.groovy.grails.commons.spring.ReloadAwareAutowireCapableBeanFactory.doCreateBean(ReloadAwareAutowireCapableBeanFactory.java:123)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
    at org.codehaus.groovy.grails.transaction.ChainedTransactionManagerPostProcessor.registerAdditionalTransactionManagers(ChainedTransactionManagerPostProcessor.java:114)
    at org.codehaus.groovy.grails.transaction.ChainedTransactionManagerPostProcessor.postProcessBeanFactory(ChainedTransactionManagerPostProcessor.java:101)
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:694)
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:633)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:461)
    at org.codehaus.groovy.grails.commons.spring.DefaultRuntimeSpringConfiguration.getApplicationContext(DefaultRuntimeSpringConfiguration.java:156)
    at org.codehaus.groovy.grails.commons.spring.GrailsRuntimeConfigurator.configure(GrailsRuntimeConfigurator.java:169)
    at org.codehaus.groovy.grails.commons.spring.GrailsRuntimeConfigurator.configure(GrailsRuntimeConfigurator.java:127)
    at org.codehaus.groovy.grails.project.loader.GrailsProjectLoader$_configureApplication_closure3.doCall(GrailsProjectLoader.groovy:134)
    at org.codehaus.groovy.grails.project.loader.GrailsProjectLoader$_configureApplication_closure3.doCall(GrailsProjectLoader.groovy)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1254)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1086)
    at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1110)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:910)
    at groovy.lang.Closure.call(Closure.java:411)
    at groovy.lang.Closure.call(Closure.java:405)
    at org.codehaus.groovy.grails.cli.api.BaseSettingsApi.profile(BaseSettingsApi.java:342)
    at org.codehaus.groovy.grails.project.loader.GrailsProjectLoader.configureApplication(GrailsProjectLoader.groovy:131)
    at org.codehaus.groovy.grails.test.runner.phase.IntegrationTestPhaseConfigurer.prepare(IntegrationTestPhaseConfigurer.groovy:59)
    at org.codehaus.groovy.grails.test.runner.phase.TestPhaseConfigurer$prepare.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:120)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callSafe(AbstractCallSite.java:89)
    at org.codehaus.groovy.grails.test.runner.GrailsProjectTestRunner$_runAllTests_closure7.doCall(GrailsProjectTestRunner.groovy:311)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1254)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1086)
    at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1110)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:910)
    at groovy.lang.Closure.call(Closure.java:411)
    at org.codehaus.groovy.runtime.DefaultGroovyMethods.callClosureForMapEntry(DefaultGroovyMethods.java:3873)
    at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:1354)
    at org.codehaus.groovy.runtime.dgm$149.invoke(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:271)
    at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:53)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
    at org.codehaus.groovy.grails.test.runner.GrailsProjectTestRunner.runAllTests(GrailsProjectTestRunner.groovy:301)
    at org.codehaus.groovy.grails.test.runner.GrailsProjectTestRunner.runAllTests(GrailsProjectTestRunner.groovy:216)
    at org.codehaus.groovy.grails.test.runner.GrailsProjectTestRunner.runAllTests(GrailsProjectTestRunner.groovy)
    at org.codehaus.groovy.grails.test.runner.GrailsProjectTestRunner$runAllTests$0.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
    at org.codehaus.groovy.grails.cli.fork.testing.ForkedGrailsTestRunner.runInstance(ForkedGrailsTestRunner.groovy:128)
    at org.codehaus.groovy.grails.cli.fork.ForkedGrailsProjectClassExecutor.run(ForkedGrailsProjectClassExecutor.groovy:74)
    at org.codehaus.groovy.grails.cli.fork.testing.ForkedGrailsTestRunner.main(ForkedGrailsTestRunner.groovy:75)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoDatastore': FactoryBean threw exception on object creation; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: Timed out while waiting for a server that matches AnyServerSelector{} after 10000 ms; nested exception is com.mongodb.MongoTimeoutException: Timed out while waiting for a server that matches AnyServerSelector{} after 10000 ms
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:151)
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:103)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1514)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
    ... 70 more
Caused by: org.springframework.dao.InvalidDataAccessResourceUsageException: Timed out while waiting for a server that matches AnyServerSelector{} after 10000 ms; nested exception is com.mongodb.MongoTimeoutException: Timed out while waiting for a server that matches AnyServerSelector{} after 10000 ms
    at org.springframework.data.mongodb.core.MongoExceptionTranslator.translateExceptionIfPossible(MongoExceptionTranslator.java:69)
    at org.springframework.data.mongodb.core.MongoTemplate.potentiallyConvertRuntimeException(MongoTemplate.java:1829)
    at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:393)
    at org.grails.datastore.mapping.mongo.MongoDatastore.initializeIndices(MongoDatastore.java:285)
    at org.grails.datastore.mapping.mongo.MongoDatastore.createMongoTemplate(MongoDatastore.java:276)
    at org.grails.datastore.mapping.mongo.MongoDatastore.afterPropertiesSet(MongoDatastore.java:221)
    at org.springframework.beans.factory.InitializingBean$afterPropertiesSet.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112)
    at org.grails.datastore.gorm.mongo.bean.factory.MongoDatastoreFactoryBean.getObject(MongoDatastoreFactoryBean.groovy:54)
    at org.grails.datastore.gorm.mongo.bean.factory.MongoDatastoreFactoryBean.getObject(MongoDatastoreFactoryBean.groovy)
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:144)
    ... 75 more
Caused by: com.mongodb.MongoTimeoutException: Timed out while waiting for a server that matches AnyServerSelector{} after 10000 ms
    at com.mongodb.BaseCluster.getServer(BaseCluster.java:87)
    at com.mongodb.DBTCPConnector.getServer(DBTCPConnector.java:654)
    at com.mongodb.DBTCPConnector.access$300(DBTCPConnector.java:39)
    at com.mongodb.DBTCPConnector$MyPort.getConnection(DBTCPConnector.java:503)
    at com.mongodb.DBTCPConnector$MyPort.get(DBTCPConnector.java:451)
    at com.mongodb.DBTCPConnector.getPrimaryPort(DBTCPConnector.java:409)
    at com.mongodb.DBCollectionImpl.createIndex(DBCollectionImpl.java:339)
    at com.mongodb.DBCollection.createIndex(DBCollection.java:564)
    at com.mongodb.DBCollection.ensureIndex(DBCollection.java:663)
    at com.mongodb.DBCollection.ensureIndex(DBCollection.java:603)
    at org.grails.datastore.mapping.mongo.MongoDatastore$6.doInDB(MongoDatastore.java:341)
    at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:391)
    ... 85 more

基于堆栈跟踪的这一部分:

nested exception is com.mongodb.MongoTimeoutException: Timed out while waiting for a server that matches AnyServerSelector{} after 10000 ms

在我看来,无论环境是“测试”,插件都试图连接到一个 mongo 实例。这是有道理的,因为如果我在我的计算机上启动一个本地 mongo,测试就会成功运行。

我花了一天半的时间在谷歌上搜索这个问题,但常见的回答是“你的 mongo 实例没有运行”。我意识到了,但为了测试我实际上并不需要它。

对于更多的上下文,此测试必须在没有任何 mongo 实例运行的 Jenkins 服务器中运行,并抛出与预期完全相同的异常。

非常感谢您对此的任何帮助。

【问题讨论】:

    标签: mongodb hibernate grails


    【解决方案1】:

    集成测试针对“完全成熟”的 grails 应用程序运行 - 如果您在 dev 和 prod 中使用数据库,那么您将需要一个用于测试的数据库。

    此外,如果您真的在做自动化测试部分,您将需要一个用于其他测试的测试数据库,所以现在就创建一个。即使此测试不使用它,它也构成了您正在测试的“完整 grails 环境”的一部分。

    在您的 Jenkins 作业中,您可以传递一个环境设置来指示测试环境为数据源使用指定的配置文件。我使用存储在 test/conf/app-config.groovy 中的特定于测试的 app-config.groovy 文件来执行此操作。该配置指向 Jenkins 服务器可以看到的长期 AWS RDS 实例(数据库不在 Jenkins 服务器上)。 Jenkins 构建步骤本质上调用:

    grails test-app -Dapp.config.location=test/conf/app-config.groovy 集成:

    (我在工作中遇到了同样的问题,刚刚为所有三个环境(开发、生产和测试)创建了 MySQL 数据库。并且可以做更多的事情,因为我们与客户一起运行,在 H2、MSSQL、Oracle 或MySQL)。

    【讨论】:

    • 感谢您的解释。所以我在概念上是错误的。我们刚刚与架构团队进行了交谈,他们允许我们在 Jenkins 上安装一个 MongoDB 插件,该插件在运行作业之前启动一个 mongo 实例,并在作业完成后停止它。现在我们可以在适当的环境中对应用进行全面测试了。
    猜你喜欢
    • 2012-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-29
    • 1970-01-01
    • 2020-07-14
    • 2015-03-04
    • 1970-01-01
    相关资源
    最近更新 更多