-
Notifications
You must be signed in to change notification settings - Fork 38.4k
Load dedicated child ApplicationContext for test instance in the TestContext framework [SPR-4632] #9309
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
Comments
Juergen Hoeller commented This has actually been debated before but was decided to be the better tradeoff overall. We also consider enabling annotation processing by default in forthcoming special environments, so that doesn't necessarily apply to test environments only. Actually, integration test XML files are not necessarily supposed to be an exact match for production bean definition files in the first place. There are always going to be some configuration differences, typically isolated into a specific XML file that's part of a config set. Since it's sufficient to have a context:annotation-config entry in one of the files in the config set, I don't think that the defaults in the test environment are bad there... Maybe not immediately expected but still not causing serious hassle either. Juergen |
Tuomas Kiviaho commented Automatic post processor registration lead to intense debugging session for me since I wasn't aware of it before and I have a custom CommonAnnotationBeanPostProcessor which lead to double post processing causing latter to crash due to it's default configuration. As workaround I just had to name my post processor identically to the default one ( (org.springframework.context.annotation.internalCommonAnnotationProcessor) preventing it from being registered. One solution could be to use org.springframework.beans.factory.ListableBeanFactory#getBeanNamesForType to ensure that beanFactory doesn't already have post processors instead of name comparison. |
Tuomas Kiviaho commented I noticed that it is possible to register processors just for test class via extendingDependencyInjectionTestExecutionListener by using test container application context as parent of a test application context which sole purpose is to instantiate test. By moving the AnnotationConfigUtils.registerAnnotationConfigProcessors from AbstractGenericContextLoader to DependencyInjectionTestExecutionListener is one way to solve this issue without API changes. By moving hooks as well from AbstractGenericContextLoader the extendability stays about the same. |
Dave Syer commented I agree with Tuomas: the test case should live in a child context, so that the behaviour of the parent context is the same as it would be in production. Can we get this into the 3.0.x roadmap? |
Neale Upstone commented Is there any hope of this making 3.2 now? It looks like there are enough related changes going in with spring-test-mvc that this should go too... |
Sam Brannen commented Hi Neal, Pending completion of related issues #10284 and #14496, it may be possible to address this issue in the 3.2 time frame, but we'll just have to see how things play out. Regards, Sam |
Sam Brannen commented FYI: I have created a branch as a sort of playground for investigating options that do not include creating a child Regards, Sam |
Neale Upstone commented Thanks. I've had a quick look, and do wonder if it's an approach that might lead to maintenance headaches in future. Are there drawbacks to the child context approach? |
Sam Brannen commented Hi Neale, Thanks for taking a look and more importantly for the quick feedback! The work in the branch is really just an exploration of one possible option, but you're right: the child context approach may well prove to be more pragmatic and elegant in the long run. In addition, introducing a child context may make the issue raised in #14113 a moot point, thus potentially killing two (or more) birds with one stone. So I'll continue investigating. ;) Cheers, Sam |
Marten Deinum commented As this would be a fix for issue #14113 is there any change of seeing this included in Spring 5.1? #14113 is an issue and with the ease of testing with Next to that I believe that enabling additional |
Marten Deinum commented Sam Brannen / Juergen Hoeller any progress/information on this? As we heavily use |
Marten Deinum commented Although creating a fresh If a test class wants access to the After some further digging, the main issue lies within the line Sam Brannen is that along the lines of your proposed solution in your specific branch? |
Sam Brannen commented Marten Deinum, you raise some interesting questions. I hadn't really pondered the scenario where the I think we would have to investigate the possibilities here in greater depth with actual prototype code.
Yes, that was the goal of my proof of concept. I would actually prefer to be able to avoid the introduction of a child context while simultaneously limiting what is applied to the test instance. The main challenge with the latter is that the core DI support in Spring is unaware of the testing framework. So there is currently no mechanism for instructing the core DI support not to do certain things (other than having the test class implement Juergen Hoeller, what do you think about introducing some sort of mechanism in the core DI support that would allow the TestContext framework to specify that only certain BPPs should be applied to the test instance? |
Sam Brannen commented FYI: Juergen Hoeller graciously and unwittingly resolved #14113 while addressing #21674. Thus, unnecessary proxying of test instances is no longer an issue as of Spring Framework 5.1 RC3. |
Since #14113 was addressed in 5.1 and due to other enhancements in the framework in the interim, we have not heard from the community about a concrete need for loading a child context in the TCF in modern Spring applications. In addition, as stated in the above discussions, introducing a child context also introduces issues of its own. In light of that, I am closing this issue. |
Eberhard Wolff opened SPR-4632 and commented
Status Quo
The
loadContext(\*\)
methods inAbstractGenericContextLoader
andAbstractGenericWebContextLoader
invokeAnnotationConfigUtils.registerAnnotationConfigProcessors(context)
.The result is that
@Autowired
,@Resource
,@Inject
, etc. all work by default, even if annotation-driven dependency injection is not explicitly configured in the test'sApplicationContext
. Consequently, if a developer is not aware of this, then errors related to the lack of explicit annotation-driven DI support in production configuration will not be noticed until after testing which is typically undesirable.Note, however, that this unexpected behavior only applies to XML-based configuration. With JavaConfig, an
AnnotatedBeanDefinitionReader
(used internally byAnnotationConfigContextLoader
andAnnotationConfigWebContextLoader
) automatically registers the annotation config processors.Furthermore,
BeanPostProcessors
may inadvertently be applied to the test instance -- even though the test is not truly a bean in theApplicationContext
. This leads to potentially problematic behavior such as accidental proxying of the test instance, as described in #14113.Deliverables
ApplicationContext
dedicated solely to the test instance (for the purpose of dependency injection and bean initialization) and set theparent
of that context to theApplicationContext
loaded by the TCF.AnnotationConfigUtils.registerAnnotationConfigProcessors()
in:AbstractGenericContextLoader
AbstractGenericWebContextLoader
Original Issue Summary
Do not enable annotation-driven DI for the entire ApplicationContext in the TestContext framework
Original Proposal
It would be better if the TestContext framework (TCF) only enabled annotation-driven dependency injection for test instances and not for the entire
ApplicationContext
.Affects: 2.5.2
Attachments:
Issue Links:
6 votes, 6 watchers
The text was updated successfully, but these errors were encountered: