'SpringBeanAutowiringSupport does not inject beans in jUnit tests
I use SpringBeanAutowiringSupport for bean injection in some objects. Problem is, that injection of beans does not work in jUnit tests. For testing is used SpringJUnit4ClassRunner.
public class DossierReportItemXlsImporterImpl implements DossierRerportItemXlsImporer {
private final Logger logger = Logger.getLogger(getClass());
// are not autowired.
@Autowired
private DossierReportService dossierReportService;
@Autowired
private DossierReportItemService dossierReportItemService;
@Autowired
private NandoCodeService nandoCodeService;
public DossierReportItemXlsImporterImpl(){
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
//...
}
public class DossierRerportItemXlsImporerTest extends AuditorServiceTest{
// injected OK
@Autowired
private DossierReportService dossierReportService;
@Autowired
private DossierReportItemService dossierReportItemService;
@Test
public void testXlsImport(){
DossierRerportItemXlsImporer importer = new DossierReportItemXlsImporterImpl();
importer.processImport(createDossierReport(), loadFile());
// ...
}
// ...
}
Does anyone have any idea, why injection using SpringBeanAutowiringSupport does not work in jUnit tests?
Solution 1:[1]
well spring + junit team have already fixed this . look this link -- >
spring unit testing
otherwise you can call the spring context and use the getBean method , but in that way you can even do it with a simple main test inside your class instead of junit test
**note if you use the spring + junit config you have to put the test-spring-context.xml into the test package
Solution 2:[2]
I made my own version that supports passing in an ApplicationContext not just limited to WebApplicationContext. This will allow it to work in both test and normal context.
/**
* This is an implementation of {@link org.springframework.web.context.support.SpringBeanAutowiringSupport} that
* has a fallback that can be used in unit tests.
*/
public final class SpringBeanAutowiringSupport {
private static final ThreadLocal<ApplicationContext> applicationContextThreadLocal = new ThreadLocal<>();
private SpringBeanAutowiringSupport() {}
public static void setApplicationContext(final ApplicationContext applicationContext) {
applicationContextThreadLocal.set(applicationContext);
}
public static void processInjectionBasedOnCurrentContext(Object target) {
var cc = ContextLoader.getCurrentWebApplicationContext();
if (cc != null) {
org.springframework.web.context.support.SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(target);
} else if (applicationContextThreadLocal.get() != null) {
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(applicationContextThreadLocal.get().getAutowireCapableBeanFactory());
bpp.processInjection(target);
}
}
public static void unload() {
applicationContextThreadLocal.remove();
}
}
To make it easier to use on tests, I add a TestExecutionListener
public class SpringBeanAutowiringSupportTestExecutionListener extends AbstractTestExecutionListener {
@Override
public void afterTestMethod(final TestContext testContext) {
SpringBeanAutowiringSupport.unload();
}
@Override
public void beforeTestMethod(final TestContext testContext) {
SpringBeanAutowiringSupport.setApplicationContext(testContext.getApplicationContext());
}
}
Then use it in my tests with
@RunWith(SpringRunner.class)
@TestExecutionListeners(listeners = {SpringBeanAutowiringSupportTestExecutionListener.class}, mergeMode = MERGE_WITH_DEFAULTS)
public class MyTest {
...
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 |
