Closed
Description
It would be nice to consider adding validation of @Autowired
on tests. For example, a user may be trying to use parameter injection of their beans and accidentally place @Autowired
on the method rather than on the parameters. For example the following:
@Test
@Autowired
@WithMockUser
void go(MessageService messageService) {
assertThat(messageService).isNotNull();
assertThat(SecurityContextHolder.getContext().getAuthentication()).isNotNull();
}
will be invoked when the test is autowired. It would fail because Spring Security's TestExecutionListener
is not invoked until the time of test rather than injection. The failure looks something like this:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'example.demo.WithMockUserAutowiredMethodTest': Injection of autowired dependencies failed; nested exception is java.lang.AssertionError:
Expecting actual not to be null
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:405)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1420)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:392)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:119)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:244)
at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:98)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$5(ClassBasedTestDescriptor.java:341)
...
Caused by: java.lang.AssertionError:
Expecting actual not to be null
at example.demo.WithMockUserAutowiredMethodTest.withMockUserWhenAutowiredMethodThenSecurityContextSetup(WithMockUserAutowiredMethodTest.java:23)
I think it would be nice to add validation around what methods are @Autowired
to ensure they are not on methods that are also annotated with JUnit Jupiter methods to give users a more clear explanation as to what is wrong.
Related Discussion: #18629 (comment)