You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@grails.apache.org by bo...@apache.org on 2026/08/13 22:33:25 UTC
(grails-core) 01/10: Add unit coverage for AbstractDatastoreInitializer and clean up IDE warnings
This is an automated email from the ASF dual-hosted git repository.
borinquenkid pushed a commit to branch test/abstract-datastore-initializer
in repository https://gitbox.apache.org/repos/asf/grails-core.git
commit f5d0465dac04bbe8c91b58fce8de5fb7d571b26a
Author: Walter Duque de Estrada <wb...@mac.com>
AuthorDate: Thu Aug 13 13:34:44 2026 -0500
Add unit coverage for AbstractDatastoreInitializer and clean up IDE warnings
Introduces a shared TestDatastoreInitializer test double and a new
AbstractDatastoreInitializerSpec covering constructors, event/message
publisher resolution, mapped-class filtering, bean registration helpers,
data-service discovery and a full configure() round trip. The existing
web-application spec is refactored to reuse the shared double instead of
its own private copy.
Also resolves several IDE-flagged issues in AbstractDatastoreInitializer:
replaces the deprecated Class#newInstance() calls with
getDeclaredConstructor().newInstance(), names previously-unused catch
parameters, swaps an equals() call for ==, types the loadDataServices
closure parameters, and makes containsRegisteredBean/getGrailsValidatorClass
static since neither depends on instance state. getCommonConfiguration,
getGrailsApplicationClass and isGrailsPresent are left as instance methods
(with explanatory @SuppressWarnings) since they are genuine override hooks
for downstream datastore initializers.
Co-Authored-By: Claude Sonnet 5 <no...@anthropic.com>
---
.../bootstrap/AbstractDatastoreInitializer.groovy | 32 +-
.../AbstractDatastoreInitializerSpec.groovy | 360 +++++++++++++++++++++
...ctDatastoreInitializerWebApplicationSpec.groovy | 5 -
.../gorm/bootstrap/TestDatastoreInitializer.groovy | 95 ++++++
4 files changed, 479 insertions(+), 13 deletions(-)
diff --git a/grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/bootstrap/AbstractDatastoreInitializer.groovy b/grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/bootstrap/AbstractDatastoreInitializer.groovy
index 510c47dcdf..5eb8112edc 100644
--- a/grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/bootstrap/AbstractDatastoreInitializer.groovy
+++ b/grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/bootstrap/AbstractDatastoreInitializer.groovy
@@ -261,7 +261,14 @@ abstract class AbstractDatastoreInitializer implements ResourceLoaderAware {
}
}
+ /**
+ * Hook subclasses can override to contribute bean definitions common to every datastore type
+ * they configure. The {@code registry} and {@code type} parameters are unused by this default
+ * no-op implementation but are part of the override contract used by overriders such as the
+ * Hibernate and MongoDB datastore initializers.
+ */
@CompileDynamic
+ @SuppressWarnings(['GrMethodMayBeStatic', 'GroovyUnusedDeclaration'])
Closure getCommonConfiguration(BeanDefinitionRegistry registry, String type) {
return {}
}
@@ -274,7 +281,7 @@ abstract class AbstractDatastoreInitializer implements ResourceLoaderAware {
}
protected boolean isMappedClass(String datastoreType, Class cls) {
- datastoreType.equals(ClassPropertyFetcher.getStaticPropertyValue(cls, GormProperties.MAPPING_STRATEGY, String))
+ datastoreType == ClassPropertyFetcher.getStaticPropertyValue(cls, GormProperties.MAPPING_STRATEGY, String)
}
abstract Closure getBeanDefinitions(BeanDefinitionRegistry beanDefinitionRegistry)
@@ -311,7 +318,7 @@ abstract class AbstractDatastoreInitializer implements ResourceLoaderAware {
}
}
loadDataServices(null)
- .each { serviceName, serviceClass ->
+ .each { String serviceName, Class<?> serviceClass ->
"$serviceName"(DatastoreServiceMethodInvokingFactoryBean, serviceClass) {
targetObject = ref("${type}Datastore")
targetMethod = 'getService'
@@ -356,7 +363,7 @@ abstract class AbstractDatastoreInitializer implements ResourceLoaderAware {
}
@CompileDynamic
- protected boolean containsRegisteredBean(Object builder, BeanDefinitionRegistry registry, String beanName) {
+ protected static boolean containsRegisteredBean(Object builder, BeanDefinitionRegistry registry, String beanName) {
registry.containsBeanDefinition(beanName) || (builder.hasProperty('springConfig') && builder.springConfig.containsBean(beanName))
}
@@ -386,7 +393,13 @@ abstract class AbstractDatastoreInitializer implements ResourceLoaderAware {
*/
protected abstract Class<AbstractDatastorePersistenceContextInterceptor> getPersistenceInterceptorClass()
+ /**
+ * Not made static: {@code getClass()} intentionally resolves the classloader of the concrete
+ * subclass instance rather than this base class, which matters when a subclass is loaded by a
+ * different (e.g. plugin/OSGi) classloader than {@link AbstractDatastoreInitializer} itself.
+ */
@CompileStatic
+ @SuppressWarnings('GrMethodMayBeStatic')
protected Class getGrailsApplicationClass() {
ClassLoader cl = getClass().getClassLoader()
if (ClassUtils.isPresent('grails.core.DefaultGrailsApplication', cl)) {
@@ -396,6 +409,7 @@ abstract class AbstractDatastoreInitializer implements ResourceLoaderAware {
}
+ @SuppressWarnings('GrMethodMayBeStatic')
protected boolean isGrailsPresent() {
ClassLoader cl = getClass().getClassLoader()
if (ClassUtils.isPresent('grails.core.DefaultGrailsApplication', cl)) {
@@ -405,7 +419,7 @@ abstract class AbstractDatastoreInitializer implements ResourceLoaderAware {
}
@CompileStatic
- protected Class getGrailsValidatorClass() {
+ protected static Class getGrailsValidatorClass() {
throw new UnsupportedOperationException('Method getGrailsValidatorClass no longer supported')
}
@@ -415,13 +429,14 @@ abstract class AbstractDatastoreInitializer implements ResourceLoaderAware {
try {
Thread.currentThread().contextClassLoader.loadClass('org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader')
return true
- } catch (e) {
+ } catch (ignored) {
return false
}
}
static void registerBeans(BeanDefinitionRegistry registry, Closure beanDefinitions) {
def classLoader = Thread.currentThread().contextClassLoader
- def beanReader = classLoader.loadClass('org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader').newInstance(registry)
+ def readerClass = classLoader.loadClass('org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader')
+ def beanReader = readerClass.getDeclaredConstructor(BeanDefinitionRegistry).newInstance(registry)
beanReader.beans(beanDefinitions)
}
}
@@ -432,14 +447,15 @@ abstract class AbstractDatastoreInitializer implements ResourceLoaderAware {
try {
Thread.currentThread().contextClassLoader.loadClass('grails.spring.BeanBuilder')
return true
- } catch (e) {
+ } catch (ignored) {
return false
}
}
static void registerBeans(BeanDefinitionRegistry registry, Closure beanDefinitions) {
def classLoader = Thread.currentThread().contextClassLoader
- def beanBuilder = classLoader.loadClass('grails.spring.BeanBuilder').newInstance()
+ def beanBuilderClass = classLoader.loadClass('grails.spring.BeanBuilder')
+ def beanBuilder = beanBuilderClass.getDeclaredConstructor().newInstance()
beanBuilder.beans(beanDefinitions)
beanBuilder.registerBeans(registry)
}
diff --git a/grails-datamapping-core/src/test/groovy/org/grails/datastore/gorm/bootstrap/AbstractDatastoreInitializerSpec.groovy b/grails-datamapping-core/src/test/groovy/org/grails/datastore/gorm/bootstrap/AbstractDatastoreInitializerSpec.groovy
new file mode 100644
index 0000000000..076f2445bb
--- /dev/null
+++ b/grails-datamapping-core/src/test/groovy/org/grails/datastore/gorm/bootstrap/AbstractDatastoreInitializerSpec.groovy
@@ -0,0 +1,360 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.grails.datastore.gorm.bootstrap
+
+import org.springframework.beans.factory.support.DefaultListableBeanFactory
+import org.springframework.beans.factory.support.RootBeanDefinition
+import org.springframework.context.support.GenericApplicationContext
+import org.springframework.context.support.StaticMessageSource
+import org.springframework.core.env.StandardEnvironment
+import spock.lang.Specification
+
+import grails.core.DefaultGrailsApplication
+import org.grails.datastore.gorm.events.ConfigurableApplicationContextEventPublisher
+import org.grails.datastore.gorm.events.DefaultApplicationEventPublisher
+import org.grails.datastore.gorm.services.DefaultTenantService
+import org.grails.datastore.gorm.services.DefaultTransactionService
+
+/**
+ * Unit coverage for the reusable configuration behaviour in {@link AbstractDatastoreInitializer},
+ * exercised through the {@link TestDatastoreInitializer} test double so no real datastore module
+ * (Hibernate, MongoDB, Neo4j, ...) is required.
+ */
+class AbstractDatastoreInitializerSpec extends Specification {
+
+ void 'the no-arg constructor uses sensible defaults'() {
+ when:
+ def initializer = new TestDatastoreInitializer()
+
+ then:
+ initializer.packages == []
+ initializer.persistentClasses == []
+ initializer.configuration instanceof StandardEnvironment
+ initializer.originalConfiguration == null
+ initializer.registerApplicationIfNotPresent
+ }
+
+ void 'a package-name constructor records the given packages'() {
+ when:
+ def initializer = new TestDatastoreInitializer('com.example', 'com.other')
+
+ then:
+ initializer.packages == ['com.example', 'com.other']
+ }
+
+ void 'a persistent-class constructor records the given classes'() {
+ when:
+ def initializer = new TestDatastoreInitializer(String, Integer)
+
+ then:
+ initializer.persistentClasses == [String, Integer]
+ }
+
+ void 'a Map configuration constructor derives a PropertyResolver but retains the original Map'() {
+ given:
+ Map config = ['foo.bar': 'baz']
+
+ when:
+ def initializer = new TestDatastoreInitializer(config, [String])
+
+ then:
+ initializer.originalConfiguration.is(config)
+ initializer.configuration.getRequiredProperty('foo.bar') == 'baz'
+ initializer.persistentClasses == [String]
+ }
+
+ void 'a PropertyResolver configuration constructor keeps the resolver as-is with no original configuration'() {
+ given:
+ def resolver = new StandardEnvironment()
+
+ when:
+ def initializer = new TestDatastoreInitializer(resolver, [String])
+
+ then:
+ initializer.configuration.is(resolver)
+ initializer.originalConfiguration == null
+ }
+
+ void 'findEventPublisher wraps the registry itself when it is a ConfigurableApplicationContext'() {
+ given:
+ def initializer = new TestDatastoreInitializer()
+ def context = new GenericApplicationContext()
+
+ expect:
+ initializer.findEventPublisher(context) instanceof ConfigurableApplicationContextEventPublisher
+
+ cleanup:
+ context.close()
+ }
+
+ void 'findEventPublisher falls back to the resource loader when the registry is not a ConfigurableApplicationContext'() {
+ given:
+ def initializer = new TestDatastoreInitializer()
+ def context = new GenericApplicationContext()
+ initializer.setResourceLoader(context)
+
+ expect:
+ initializer.findEventPublisher(new DefaultListableBeanFactory()) instanceof ConfigurableApplicationContextEventPublisher
+
+ cleanup:
+ context.close()
+ }
+
+ void 'findEventPublisher defaults to a DefaultApplicationEventPublisher when neither source is available'() {
+ given:
+ def initializer = new TestDatastoreInitializer()
+
+ expect:
+ initializer.findEventPublisher(new DefaultListableBeanFactory()) instanceof DefaultApplicationEventPublisher
+ }
+
+ void 'findMessageSource uses the registry itself when it is a MessageSource'() {
+ given:
+ def initializer = new TestDatastoreInitializer()
+ def context = new GenericApplicationContext()
+
+ expect:
+ initializer.findMessageSource(context).is(context)
+
+ cleanup:
+ context.close()
+ }
+
+ void 'findMessageSource falls back to the resource loader when the registry is not a MessageSource'() {
+ given:
+ def initializer = new TestDatastoreInitializer()
+ def context = new GenericApplicationContext()
+ initializer.setResourceLoader(context)
+
+ expect:
+ initializer.findMessageSource(new DefaultListableBeanFactory()).is(context)
+
+ cleanup:
+ context.close()
+ }
+
+ void 'findMessageSource defaults to a fresh StaticMessageSource when neither source is available'() {
+ given:
+ def initializer = new TestDatastoreInitializer()
+
+ expect:
+ initializer.findMessageSource(new DefaultListableBeanFactory()) instanceof StaticMessageSource
+ }
+
+ void 'setResourceLoader rebuilds the resource pattern resolver around the given loader'() {
+ given:
+ def initializer = new TestDatastoreInitializer()
+ def loader = new GenericApplicationContext()
+
+ when:
+ initializer.setResourceLoader(loader)
+
+ then:
+ initializer.resourcePatternResolver.resourceLoader.is(loader)
+
+ cleanup:
+ loader.close()
+ }
+
+ void 'isMappedClass returns true only when the static mapWith property matches the datastore type'() {
+ given:
+ def initializer = new TestDatastoreInitializer()
+
+ expect:
+ initializer.isMappedClass('mongo', MongoEntity)
+ !initializer.isMappedClass('sql', MongoEntity)
+ !initializer.isMappedClass('mongo', UnmappedEntity)
+ }
+
+ void 'collectMappedClasses returns every persistent class when this is not a secondary datastore'() {
+ given:
+ def initializer = new TestDatastoreInitializer([MongoEntity, SqlEntity, UnmappedEntity])
+
+ expect:
+ initializer.collectMappedClasses('mongo') == [MongoEntity, SqlEntity, UnmappedEntity]
+ }
+
+ void 'collectMappedClasses filters to only the classes mapped to the given type for a secondary datastore'() {
+ given:
+ def initializer = new TestDatastoreInitializer([MongoEntity, SqlEntity, UnmappedEntity])
+ initializer.setSecondaryDatastore(true)
+
+ expect:
+ initializer.collectMappedClasses('mongo') == [MongoEntity]
+ initializer.collectMappedClasses('sql') == [SqlEntity]
+ }
+
+ void 'containsRegisteredBean returns true when the registry already contains a bean definition with that name'() {
+ given:
+ def registry = new DefaultListableBeanFactory()
+ registry.registerBeanDefinition('fooBean', new RootBeanDefinition(Object))
+ def initializer = new TestDatastoreInitializer()
+
+ expect:
+ initializer.containsRegisteredBean(new Object(), registry, 'fooBean')
+ }
+
+ void 'containsRegisteredBean falls back to a springConfig-aware builder when the registry does not know the bean'() {
+ given:
+ def registry = new DefaultListableBeanFactory()
+ def builder = new BeanBuilderStub(springConfig: new SpringConfigStub(beanNames: ['fooBean'] as Set))
+ def initializer = new TestDatastoreInitializer()
+
+ expect:
+ initializer.containsRegisteredBean(builder, registry, 'fooBean')
+ !initializer.containsRegisteredBean(builder, registry, 'otherBean')
+ }
+
+ void 'containsRegisteredBean returns false when neither the registry nor the builder know the bean'() {
+ given:
+ def registry = new DefaultListableBeanFactory()
+ def initializer = new TestDatastoreInitializer()
+
+ expect:
+ !initializer.containsRegisteredBean(new Object(), registry, 'fooBean')
+ }
+
+ void 'getCommonConfiguration returns a no-op closure by default'() {
+ given:
+ def initializer = new TestDatastoreInitializer()
+
+ when:
+ def closure = initializer.getCommonConfiguration(new DefaultListableBeanFactory(), 'foo')
+
+ then:
+ closure instanceof Closure
+ closure() == null
+ }
+
+ void 'loadDataServices discovers the Service implementations declared for this module'() {
+ given:
+ def initializer = new TestDatastoreInitializer()
+
+ when:
+ def services = initializer.loadDataServices()
+
+ then:
+ services.defaultTransactionService == DefaultTransactionService
+ services.defaultTenantService == DefaultTenantService
+ }
+
+ void 'loadDataServices namespaces service names under the secondary datastore type when given'() {
+ given:
+ def initializer = new TestDatastoreInitializer()
+
+ when:
+ def services = initializer.loadDataServices('foo')
+
+ then:
+ services.fooDefaultTransactionService == DefaultTransactionService
+ services.fooDefaultTenantService == DefaultTenantService
+ }
+
+ void 'isGrailsPresent and getGrailsApplicationClass detect grails-core on the classpath'() {
+ given:
+ def initializer = new TestDatastoreInitializer()
+
+ expect:
+ initializer.isGrailsPresent()
+ initializer.getGrailsApplicationClass() == DefaultGrailsApplication
+ }
+
+ void 'getGrailsValidatorClass is no longer supported'() {
+ given:
+ def initializer = new TestDatastoreInitializer()
+
+ when:
+ initializer.getGrailsValidatorClass()
+
+ then:
+ thrown(UnsupportedOperationException)
+ }
+
+ void 'getAdditionalBeansConfiguration registers a transaction manager, persistence interceptor, aggregator and every data service'() {
+ given:
+ def registry = new DefaultListableBeanFactory()
+ def initializer = new TestDatastoreInitializer()
+
+ when:
+ def beanDefinitions = initializer.getAdditionalBeansConfiguration(registry, 'foo')
+ AbstractDatastoreInitializer.GroovyBeanReaderInit.registerBeans(registry, beanDefinitions)
+
+ then:
+ registry.containsBeanDefinition('fooTransactionManager')
+ registry.isAlias('transactionManager')
+ registry.getAliases('fooTransactionManager') as Set == ['transactionManager'] as Set
+ registry.containsBeanDefinition('fooPersistenceInterceptor')
+ registry.containsBeanDefinition('fooPersistenceContextInterceptorAggregator')
+ registry.containsBeanDefinition('defaultTransactionService')
+ registry.containsBeanDefinition('defaultTenantService')
+ !registry.containsBeanDefinition('fooOpenSessionInViewInterceptor')
+ }
+
+ void 'getAdditionalBeansConfiguration does not alias an already-registered transactionManager bean'() {
+ given:
+ def registry = new DefaultListableBeanFactory()
+ registry.registerBeanDefinition('transactionManager', new RootBeanDefinition(Object))
+ def initializer = new TestDatastoreInitializer()
+
+ when:
+ def beanDefinitions = initializer.getAdditionalBeansConfiguration(registry, 'foo')
+ AbstractDatastoreInitializer.GroovyBeanReaderInit.registerBeans(registry, beanDefinitions)
+
+ then:
+ registry.containsBeanDefinition('fooTransactionManager')
+ !registry.isAlias('transactionManager')
+ registry.getBeanDefinition('transactionManager').beanClassName == Object.name
+ }
+
+ void 'configure builds a fully refreshed application context containing the declared beans'() {
+ given:
+ def initializer = new TestDatastoreInitializer()
+ initializer.beanDefinitions = { -> "sampleBean"(String, 'hello') }
+
+ when:
+ def context = initializer.configure()
+
+ then:
+ context.isActive()
+ context.getBean('sampleBean', String) == 'hello'
+
+ cleanup:
+ context.close()
+ }
+
+ static class MongoEntity {
+ static mapWith = 'mongo'
+ }
+
+ static class SqlEntity {
+ static mapWith = 'sql'
+ }
+
+ static class UnmappedEntity {
+ }
+
+ static class SpringConfigStub {
+ Set<String> beanNames
+ boolean containsBean(String name) { name in beanNames }
+ }
+
+ static class BeanBuilderStub {
+ SpringConfigStub springConfig
+ }
+}
diff --git a/grails-datamapping-core/src/test/groovy/org/grails/datastore/gorm/bootstrap/AbstractDatastoreInitializerWebApplicationSpec.groovy b/grails-datamapping-core/src/test/groovy/org/grails/datastore/gorm/bootstrap/AbstractDatastoreInitializerWebApplicationSpec.groovy
index 0a76590f3a..7d77719c2d 100644
--- a/grails-datamapping-core/src/test/groovy/org/grails/datastore/gorm/bootstrap/AbstractDatastoreInitializerWebApplicationSpec.groovy
+++ b/grails-datamapping-core/src/test/groovy/org/grails/datastore/gorm/bootstrap/AbstractDatastoreInitializerWebApplicationSpec.groovy
@@ -57,9 +57,4 @@ class AbstractDatastoreInitializerWebApplicationSpec extends Specification {
expect:
!isWeb(new DefaultListableBeanFactory())
}
-
- static class TestDatastoreInitializer extends AbstractDatastoreInitializer {
- Closure getBeanDefinitions(BeanDefinitionRegistry beanDefinitionRegistry) { { -> } }
- protected Class getPersistenceInterceptorClass() { null }
- }
}
diff --git a/grails-datamapping-core/src/test/groovy/org/grails/datastore/gorm/bootstrap/TestDatastoreInitializer.groovy b/grails-datamapping-core/src/test/groovy/org/grails/datastore/gorm/bootstrap/TestDatastoreInitializer.groovy
new file mode 100644
index 0000000000..a051d2792e
--- /dev/null
+++ b/grails-datamapping-core/src/test/groovy/org/grails/datastore/gorm/bootstrap/TestDatastoreInitializer.groovy
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.grails.datastore.gorm.bootstrap
+
+import org.springframework.beans.factory.support.BeanDefinitionRegistry
+import org.springframework.core.env.PropertyResolver
+
+import org.grails.datastore.gorm.support.AbstractDatastorePersistenceContextInterceptor
+import org.grails.datastore.mapping.core.Datastore
+
+/**
+ * Minimal concrete {@link AbstractDatastoreInitializer} used to exercise the abstract
+ * class's own behaviour in unit tests without depending on a real datastore module
+ * (Hibernate, MongoDB, Neo4j, ...).
+ *
+ * <p>{@link #beanDefinitions} and {@link #persistenceInterceptorClass} default to
+ * harmless no-op implementations but can be overridden per-test.
+ */
+class TestDatastoreInitializer extends AbstractDatastoreInitializer {
+
+ Closure beanDefinitions = { -> }
+ Class<AbstractDatastorePersistenceContextInterceptor> persistenceInterceptorClass = TestPersistenceContextInterceptor
+
+ TestDatastoreInitializer() {
+ super()
+ }
+
+ TestDatastoreInitializer(ClassLoader classLoader, String... packages) {
+ super(classLoader, packages)
+ }
+
+ TestDatastoreInitializer(String... packages) {
+ super(packages)
+ }
+
+ TestDatastoreInitializer(Collection<Class> persistentClasses) {
+ super(persistentClasses)
+ }
+
+ TestDatastoreInitializer(Class... persistentClasses) {
+ super(persistentClasses)
+ }
+
+ TestDatastoreInitializer(PropertyResolver configuration, Collection<Class> persistentClasses) {
+ super(configuration, persistentClasses)
+ }
+
+ TestDatastoreInitializer(PropertyResolver configuration, Class... persistentClasses) {
+ super(configuration, persistentClasses)
+ }
+
+ TestDatastoreInitializer(PropertyResolver configuration, String... packages) {
+ super(configuration, packages)
+ }
+
+ TestDatastoreInitializer(Map configuration, Collection<Class> persistentClasses) {
+ super(configuration, persistentClasses)
+ }
+
+ TestDatastoreInitializer(Map configuration, Class... persistentClasses) {
+ super(configuration, persistentClasses)
+ }
+
+ @Override
+ Closure getBeanDefinitions(BeanDefinitionRegistry beanDefinitionRegistry) {
+ beanDefinitions
+ }
+
+ @Override
+ protected Class<AbstractDatastorePersistenceContextInterceptor> getPersistenceInterceptorClass() {
+ persistenceInterceptorClass
+ }
+
+ static class TestPersistenceContextInterceptor extends AbstractDatastorePersistenceContextInterceptor {
+ TestPersistenceContextInterceptor(Datastore datastore) {
+ super(datastore)
+ }
+ }
+}