Skip to content

@TestExecutionListeners is not fully supported as a meta-annotation [SPR-12661] #17261

Closed
@spring-projects-issues

Description

@spring-projects-issues

John Bass opened SPR-12661 and commented

Status Quo

When using TestNG and deriving a test from AbstractTestNGSpringContextTests, @TestExecutionListeners as a meta-annotation doesn't seem to be working.

Here's a little 3-class test:

@Target({TYPE, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Documented
@TestExecutionListeners(listeners=MyTestExecutionListener.class, mergeMode=MergeMode.MERGE_WITH_DEFAULTS)
public @interface Composed {
}
public class MyTestExecutionListener extends AbstractTestExecutionListener {
	private static final Logger logger = LoggerFactory.getLogger( MyTestExecutionListener.class );
	
	@Override
	public void prepareTestInstance( final TestContext testContext ) throws Exception {
		logger.trace( "prepareTestInstance()" );
	}

}
@ContextConfiguration
@Composed
public class Experiment extends AbstractTestNGSpringContextTests {
	@Configuration
	static class Configurer {
		@Bean
		public Object object() {
			return new Object();
		}
	}
	
	@Test
	public void aTest() {
	}
}

Here's some output when this is run:

[org.springframework.test.context.BootstrapUtils] - Instantiating TestContextBootstrapper from class [org.springframework.test.context.support.DefaultTestContextBootstrapper]
[org.springframework.test.context.support.ContextLoaderUtils] - Retrieved @ContextConfiguration attributes [{name=, value=[], classes=[], loader=interface org.springframework.test.context.ContextLoader, locations=[], initializers=[], inheritLocations=true, inheritInitializers=true}] for declaring class [com.comcast.cpt.test.Experiment].
[org.springframework.test.context.support.ContextLoaderUtils] - Resolved context configuration attributes: [ContextConfigurationAttributes@5a49cb8c declaringClass = 'com.comcast.cpt.test.Experiment', classes = '{}', locations = '{}', inheritLocations = true, initializers = '{}', inheritInitializers = true, name = [null], contextLoaderClass = 'org.springframework.test.context.ContextLoader']
[org.springframework.test.context.support.DefaultTestContextBootstrapper] - Resolving ContextLoader for context configuration attributes [ContextConfigurationAttributes@5a49cb8c declaringClass = 'com.comcast.cpt.test.Experiment', classes = '{}', locations = '{}', inheritLocations = true, initializers = '{}', inheritInitializers = true, name = [null], contextLoaderClass = 'org.springframework.test.context.ContextLoader']
[org.springframework.test.context.support.DefaultTestContextBootstrapper] - Using ContextLoader class [org.springframework.test.context.support.DelegatingSmartContextLoader] for test class [com.comcast.cpt.test.Experiment]
[org.springframework.test.context.support.DefaultTestContextBootstrapper] - Processing locations and classes for context configuration attributes [ContextConfigurationAttributes@5a49cb8c declaringClass = 'com.comcast.cpt.test.Experiment', classes = '{}', locations = '{}', inheritLocations = true, initializers = '{}', inheritInitializers = true, name = [null], contextLoaderClass = 'org.springframework.test.context.ContextLoader']
[org.springframework.test.context.support.AbstractDelegatingSmartContextLoader] - Delegating to GenericXmlContextLoader to process context configuration [ContextConfigurationAttributes@5a49cb8c declaringClass = 'com.comcast.cpt.test.Experiment', classes = '{}', locations = '{}', inheritLocations = true, initializers = '{}', inheritInitializers = true, name = [null], contextLoaderClass = 'org.springframework.test.context.ContextLoader'].
[org.springframework.test.context.support.AbstractContextLoader] - Did not detect default resource location for test class [com.comcast.cpt.test.Experiment]: class path resource [com/comcast/cpt/test/Experiment-context.xml] does not exist
[org.springframework.test.context.support.AbstractContextLoader] - Could not detect default resource locations for test class [com.comcast.cpt.test.Experiment]: no resource found for suffixes {-context.xml}.
[org.springframework.test.context.support.AbstractDelegatingSmartContextLoader] - Delegating to AnnotationConfigContextLoader to process context configuration [ContextConfigurationAttributes@5a49cb8c declaringClass = 'com.comcast.cpt.test.Experiment', classes = '{}', locations = '{}', inheritLocations = true, initializers = '{}', inheritInitializers = true, name = [null], contextLoaderClass = 'org.springframework.test.context.ContextLoader'].
[org.springframework.test.context.support.AbstractDelegatingSmartContextLoader] - AnnotationConfigContextLoader detected default configuration classes for context configuration [ContextConfigurationAttributes@5a49cb8c declaringClass = 'com.comcast.cpt.test.Experiment', classes = '{class com.comcast.cpt.test.Experiment$Configurer}', locations = '{}', inheritLocations = true, initializers = '{}', inheritInitializers = true, name = [null], contextLoaderClass = 'org.springframework.test.context.ContextLoader'].
[org.springframework.test.context.support.ApplicationContextInitializerUtils] - Processing context initializers for context configuration attributes [ContextConfigurationAttributes@5a49cb8c declaringClass = 'com.comcast.cpt.test.Experiment', classes = '{class com.comcast.cpt.test.Experiment$Configurer}', locations = '{}', inheritLocations = true, initializers = '{}', inheritInitializers = true, name = [null], contextLoaderClass = 'org.springframework.test.context.ContextLoader']
[org.springframework.test.context.support.ActiveProfilesUtils] - Could not find an 'annotation declaring class' for annotation type [org.springframework.test.context.ActiveProfiles] and class [com.comcast.cpt.test.Experiment]

// notice this interesting line ...
[org.springframework.test.context.support.DefaultTestContextBootstrapper] - Retrieved @TestExecutionListeners attributes [{value=[class org.springframework.test.context.web.ServletTestExecutionListener,class org.springframework.test.context.support.DependencyInjectionTestExecutionListener,class org.springframework.test.context.support.DirtiesContextTestExecutionListener], listeners=[], inheritListeners=true, mergeMode=REPLACE_DEFAULTS}] for declaring class [com.comcast.cpt.test.Composed].

[org.springframework.test.context.support.DefaultTestContextBootstrapper] - Retrieved @TestExecutionListeners attributes [{value=[class org.springframework.test.context.web.ServletTestExecutionListener,class org.springframework.test.context.support.DependencyInjectionTestExecutionListener,class org.springframework.test.context.support.DirtiesContextTestExecutionListener], listeners=[], inheritListeners=true, mergeMode=REPLACE_DEFAULTS}] for declaring class [org.springframework.test.context.testng.AbstractTestNGSpringContextTests].
[org.springframework.test.context.support.DefaultTestContextBootstrapper] - Could not instantiate TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [javax/servlet/ServletContext]
[org.springframework.test.context.support.DefaultTestContextBootstrapper] - Could not instantiate TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [javax/servlet/ServletContext]
[org.springframework.test.context.support.DefaultTestContextBootstrapper] - Using TestExecutionListeners: [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@223dd567, org.springframework.test.context.support.DirtiesContextTestExecutionListener@9856ec1, org.springframework.test.context.support.DependencyInjectionTestExecutionListener@172a45c9, org.springframework.test.context.support.DirtiesContextTestExecutionListener@584b9b00]
[org.springframework.test.context.TestContextManager] - Registering TestExecutionListener: org.springframework.test.context.support.DependencyInjectionTestExecutionListener@223dd567
[org.springframework.test.context.TestContextManager] - Registering TestExecutionListener: org.springframework.test.context.support.DirtiesContextTestExecutionListener@9856ec1
[org.springframework.test.context.TestContextManager] - Registering TestExecutionListener: org.springframework.test.context.support.DependencyInjectionTestExecutionListener@172a45c9
[org.springframework.test.context.TestContextManager] - Registering TestExecutionListener: org.springframework.test.context.support.DirtiesContextTestExecutionListener@584b9b00
[TestNG] Running:
  /private/var/folders/h1/s64jf53x51gcgns7trlqc230074rk5/T/testng-eclipse--225524899/testng-customsuite.xml

[org.springframework.test.context.TestContextManager] - beforeTestClass(): class [com.comcast.cpt.test.Experiment]
[org.springframework.test.context.TestContextManager] - prepareTestInstance(): instance [com.comcast.cpt.test.Experiment@44875666]
[org.springframework.test.context.support.DependencyInjectionTestExecutionListener] - Performing dependency injection for test context [[DefaultTestContext@19264fa9 testClass = Experiment, testInstance = com.comcast.cpt.test.Experiment@44875666, testMethod = [null], testException = [null], mergedContextConfiguration = [MergedContextConfiguration@2237ed25 testClass = Experiment, locations = '{}', classes = '{class com.comcast.cpt.test.Experiment$Configurer}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]].
[org.springframework.test.context.support.AbstractDelegatingSmartContextLoader] - Delegating to AnnotationConfigContextLoader to load context from [MergedContextConfiguration@2237ed25 testClass = Experiment, locations = '{}', classes = '{class com.comcast.cpt.test.Experiment$Configurer}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]].
[org.springframework.test.context.support.AbstractGenericContextLoader] - Loading ApplicationContext for merged context configuration [[MergedContextConfiguration@2237ed25 testClass = Experiment, locations = '{}', classes = '{class com.comcast.cpt.test.Experiment$Configurer}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]].
[org.springframework.test.context.support.AnnotationConfigContextLoader] - Registering annotated classes: {class com.comcast.cpt.test.Experiment$Configurer}
[org.springframework.core.io.support.SpringFactoriesLoader] - Loaded [org.springframework.beans.BeanInfoFactory] names: [org.springframework.beans.ExtendedBeanInfoFactory]
[org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate] - Storing ApplicationContext in cache under key [[MergedContextConfiguration@2237ed25 testClass = Experiment, locations = '{}', classes = '{class com.comcast.cpt.test.Experiment$Configurer}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]
[org.springframework.test.context.cache] - Spring test ApplicationContext cache statistics: [ContextCache@50b7c740 size = 1, hitCount = 0, missCount = 1, parentContextCount = 0]
[org.springframework.test.context.support.DependencyInjectionTestExecutionListener] - Performing dependency injection for test context [[DefaultTestContext@19264fa9 testClass = Experiment, testInstance = com.comcast.cpt.test.Experiment@44875666, testMethod = [null], testException = [null], mergedContextConfiguration = [MergedContextConfiguration@2237ed25 testClass = Experiment, locations = '{}', classes = '{class com.comcast.cpt.test.Experiment$Configurer}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]].
[org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate] - Retrieved ApplicationContext from cache with key [[MergedContextConfiguration@2237ed25 testClass = Experiment, locations = '{}', classes = '{class com.comcast.cpt.test.Experiment$Configurer}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]
[org.springframework.test.context.cache] - Spring test ApplicationContext cache statistics: [ContextCache@50b7c740 size = 1, hitCount = 1, missCount = 1, parentContextCount = 0]
[org.springframework.test.context.TestContextManager] - beforeTestMethod(): instance [com.comcast.cpt.test.Experiment@44875666], method [public void com.comcast.cpt.test.Experiment.aTest()]
[org.springframework.test.context.TestContextManager] - afterTestMethod(): instance [com.comcast.cpt.test.Experiment@44875666], method [public void com.comcast.cpt.test.Experiment.aTest()], exception [null]
[org.springframework.test.context.support.DirtiesContextTestExecutionListener] - After test method: context [DefaultTestContext@19264fa9 testClass = Experiment, testInstance = com.comcast.cpt.test.Experiment@44875666, testMethod = aTest@Experiment, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@2237ed25 testClass = Experiment, locations = '{}', classes = '{class com.comcast.cpt.test.Experiment$Configurer}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]], class dirties context [false], class mode [null], method dirties context [false].
[org.springframework.test.context.support.DirtiesContextTestExecutionListener] - After test method: context [DefaultTestContext@19264fa9 testClass = Experiment, testInstance = com.comcast.cpt.test.Experiment@44875666, testMethod = aTest@Experiment, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@2237ed25 testClass = Experiment, locations = '{}', classes = '{class com.comcast.cpt.test.Experiment$Configurer}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]], class dirties context [false], class mode [null], method dirties context [false].
[org.springframework.test.context.TestContextManager] - afterTestClass(): class [com.comcast.cpt.test.Experiment]
[org.springframework.test.context.support.DirtiesContextTestExecutionListener] - After test class: context [DefaultTestContext@19264fa9 testClass = Experiment, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [MergedContextConfiguration@2237ed25 testClass = Experiment, locations = '{}', classes = '{class com.comcast.cpt.test.Experiment$Configurer}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]], dirtiesContext [false].
[org.springframework.test.context.support.DirtiesContextTestExecutionListener] - After test class: context [DefaultTestContext@19264fa9 testClass = Experiment, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [MergedContextConfiguration@2237ed25 testClass = Experiment, locations = '{}', classes = '{class com.comcast.cpt.test.Experiment$Configurer}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]], dirtiesContext [false].

Analysis

In the above log output, it's clear that the listeners declared via @TestExecutionListeners on @Composed are somehow getting set to the listeners declared via @TestExecutionListeners on AbstractTestNGSpringContextTests.


Affects: 4.1 GA

Issue Links:

Metadata

Metadata

Assignees

Labels

in: testIssues in the test modulestatus: duplicateA duplicate of another issue

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions