Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@ActiveProfiles not applied to implicit @ContextHierarchy parent context [SPR-13462] #18042

Closed
spring-projects-issues opened this issue Sep 11, 2015 · 4 comments

Comments

@spring-projects-issues
Copy link
Collaborator

@spring-projects-issues spring-projects-issues commented Sep 11, 2015

Jimmy Praet opened SPR-13462 and commented

We have an abstract base class for our tests that declares some common @ContextConfiguration. In some of the loaded context configurations we are using profiles (for example to switch between DB2 datasource and embedded derby datasource).

In our concrete test classes we extend the base class, and configure an @ContextHierarchy so the context of the base class acts as a parent application context. We want to be able to choose between DB2 and embedded derby on the concrete test class with @ActiveProfiles, but this seems to have no effect on the beans in the parent context. If we define the @ActiveProfiles on the parent, it is working.

This code snippet reproduces the problem:

@ContextHierarchy(@ContextConfiguration(classes = ChildConfig.class))
@ActiveProfiles("embedded")
public class ActiveProfilesContextHierarchyTest extends Parent {

	@Autowired
	private String dataSource;

	@Test
	public void testActiveProfilesWithContextHierarchy() {
		assertEquals("derby", dataSource);
	}
}

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { DefaultParentConfig.class, TestParentConfig.class })
class Parent {
}

@Configuration
@Profile("default")
class DefaultParentConfig {

	@Bean
	public String dataSource() {
		return "DB2";
	}
}

@Configuration
@Profile("embedded")
class TestParentConfig {

	@Bean
	public String dataSource() {
		return "derby";
	}
}

@Configuration
class ChildConfig {
}

Is this a bug or is it designed to work like that? If it's not a bug, do you have any recommendations to achieve the same effect with another approach?


Affects: 3.2.1

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Sep 11, 2015

Sam Brannen commented

This is by design.

Classes are not permitted to force their local configuration on parent classes. Doing so would essentially make it impossible for the parent class to serve as a superclass of more than one class... which would defeat the purpose of having a parent class to begin with.

As for an alternative approach, I can't think of anything off the top of my head that would allow you to use a class hierarchy to achieve this.

The straightforward (but not so pretty) approach would be to simply copy the parent config to the subclasses.

Using an ApplicationContextInitializer or an ActiveProfilesResolver might prove useful, but I'd have to investigate it further.

Let me know if any of these tips help you out. If not, I'll dig deeper at a later date.

Regards,

Sam

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Sep 11, 2015

Sam Brannen commented

Resolving as Works as Designed.

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Sep 11, 2015

Jimmy Praet commented

Thanks for the quick feedback. I'll have a look at the ApplicationContextInitializer / ActiveProfilesResolver.

Note that the @ActiveProfiles does get applied to the configuration in the parent class if I don't use a @ContextHierarchy. But I want to use the hierarchy to take advantage of the application context caching. All tests with "default" profile can share the same cached parent context, and all tests with "embedded" profile can share another cached parent context.

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Sep 14, 2015

Jimmy Praet commented

As a workaround I implemented a custom TestContextBootstrapper that I can register on the parent class with @BootstrapWith.

The boostrapper overrides the processMergedContextConfiguration(MergedContextConfiguration) method to register the active profiles of the child class with its parent MergedContextConfiguration.

Loading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants