Autowired applicationContext is null in JUnit 5 - spring

I'm trying to migrate my spring applications to test with JUnit 5. It worked fine with JUnit 4. My problem is that I can't access the application context, it is null, but should be an object. I've included imports etc, in case something is wrong there.
Test:
package com.mycompany.mavenspringjunit5;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
#SpringJUnitConfig(locations = "/test-config.xml")
public class MainTest
{
#Autowired
ApplicationContext applicationContext;
#Autowired
Integer number;
// fails
#Test
public void testGivenAppContext_WhenInjected_ThenItShouldNotBeNull()
{
System.out.println("number: " + number);
Assertions.assertNotNull(applicationContext, "applicationContext should not be null");
}
// works
#Test
public void testDoStuff()
{
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("/test-config.xml");
Main instance = ctx.getBean(Main.class);
instance.doStuff();
}
}
Main:
package com.mycompany.mavenspringjunit5;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
#Component
public class Main
{
#Autowired
Integer number;
#Autowired
ApplicationContext applicationContext;
public static void main(String[] args)
{
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
ctx.getBean(Main.class).doStuff();
}
void doStuff()
{
System.out.println("The number is " + number);
System.out.println("applicationContext " + applicationContext);
}
}
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany</groupId>
<artifactId>MavenSpringJunit5</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring.version>5.3.4</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.8.0-M1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
test-config.xml (in the directory "....\MavenSpringJunit5\src\test\resources\test-config.xml"):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<context:annotation-config />
<context:component-scan base-package="com.mycompany.mavenspringjunit5"/>
<bean id="number" class="java.lang.Integer">
<constructor-arg value="42" />
</bean>
</beans>
Output:
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.mycompany.mavenspringjunit5.MainTest
The number is 42
applicationContext org.springframework.context.support.ClassPathXmlApplicationContext#51521cc1, started on Mon Feb 22 10:49:15 CET 2021
number: null
Tests run: 2, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.884 sec <<< FAILURE!
com.mycompany.mavenspringjunit5.MainTest.testGivenAppContext_WhenInjected_ThenItShouldNotBeNull() Time elapsed: 0.009 sec <<< FAILURE!
org.opentest4j.AssertionFailedError: applicationContext should not be null ==> expected: not <null>
at org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:39)
at org.junit.jupiter.api.Assertions.fail(Assertions.java:118)
at org.junit.jupiter.api.AssertNotNull.failNull(AssertNotNull.java:47)
at org.junit.jupiter.api.AssertNotNull.assertNotNull(AssertNotNull.java:36)
at org.junit.jupiter.api.Assertions.assertNotNull(Assertions.java:292)
at com.mycompany.mavenspringjunit5.MainTest.testGivenAppContext_WhenInjected_ThenItShouldNotBeNull(MainTest.java:24)

Tested it and tests run fine in my IDE (Intellij) running the same with your provided pom.xml fails.
You need to upgrade the maven-surefire-plugin to properly detect and execute the classes.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
</plugin>
</plugins>
</build>
This is also expressed in the Junit5 documentation.

Related

Spring Nosuchbeanexception

I have created simple spring core application
,while trying to execute it I am getting NoSuch bean defined exception even though I have defined particular bean in config
Here are my files
#config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="reportService" class="com.nagesh.sample.ReportServie"/>
</beans>
object class
repoService.java
`package com.nagesh.sample;
public class ReportService {
public void display() {
System.out.println("Hi, Welcome to Report Generation application");
}
}
main class file
mainclass
package com.nagesh.spring.Sample;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.nagesh.sample.ReportService;
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
ApplicationContext context =
new ClassPathXmlApplicationContext("classpath*:config.xml");
ReportService reportService =
(ReportService) context.getBean("reportService");
reportService.display();
}
}`
here is pom.xml file
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.nagesh.spring</groupId>
<artifactId>Sample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Sample</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
</dependencies>
</project>`
help me to resolve this
Thanks in advance
One Error :
<bean id="reportService" class="com.nagesh.sample.ReportServie"/>
changed it to
<bean id="reportService" class="com.nagesh.sample.ReportService"/>
Job Done :)

Error creating bean with name 'opBean' defined in class path resource [applicationContext.xml]

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'opBean' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: com/springlearn/operation (wrong name: com/springlearn/Operation)
Operation.java
package com.springlearn;
public class Operation {
public void msg() {System.out.println("MSG Invoked");}
public int m() {
System.out.println("M invoked");
return 2;
}
public int k() {
System.out.println("K invoked");
return 3;
}
}
TrackOperation.java
package com.springlearn;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
#Aspect
public class TrackOperation {
#Pointcut("execution(* operation .*(..))")
public void k() {
}
#Before("k()")
public void myadvice(JoinPoint jp) {
System.out.println("Additional Concern");
}
}
Test.java
package com.springlearn;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test
{
public static void main( String[] args )
{
ApplicationContext context= new ClassPathXmlApplicationContext("applicationContext.xml");
Operation e=(Operation)context.getBean("opBean");
System.out.println("Calling MSG");
e.msg();
System.out.println("Calling M");
e.m();
System.out.println("Calling K");
e.k();
}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="opBean" class="com.springlearn.Operation"> </bean>
<bean id="trackMyBean" class="com.springlearn.TrackOperation"></bean>
<bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"></bean>
</beans>
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>SpringLearn</groupId>
<artifactId>springlearn</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springlearn</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>3.0.5.RELEASE</spring.version>
</properties>
<dependencies>
<!-- Spring 3 dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.7.0</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7.0</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.9</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Make sure that in your aspect class the Target object class is spelt correctly under the pointcut expression
#Pointcut("execution(* Operation.*(..))")
//Operation class instead of operation case sensitivity

Spring boot #Configurable

I'm trying to configure Autowired in non-spring managed class under spring boot application.
I run successfully this under web application deployed under tomcat server.
But when i want run this under spring boot nothing works.
I made very simple app to check this functionality:
Console result from web app int tomcat:
...:::TEST CONTROLLER
...:::TEST autowired in cotrnoller: com.mycompany.test_aop.Test#30ea7445
...:::NEW
...:::Check: com.mycompany.test_aop.Test#30ea7445
Console result from spring boot app:
...:::TEST CONTROLLER
...:::TEST autowired in cotrnoller: com.mycompany.test_aop.Test#627ae77d
...:::NEW
...:::Check: null
I read a lot of topics hot to configure spring boot app but nothing works.
I trying set param -javaagent to spring-instrument.jar but no effect.
I struggle with this for three days but no effect
App:
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pl.com.eurohost</groupId>
<artifactId>aop_test</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<repositories>
<repository>
<id>unknown-jars-temp-repo</id>
<name>A temporary repository created by NetBeans for libraries and jars it could not identify. Please replace the dependencies in this repository with correct ones and delete this repository.</name>
<url>file:${project.basedir}/lib</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>1.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>1.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>1.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>1.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.2.5.RELEASE</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-instrument</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-agent</artifactId>
<version>2.5.6.SEC03</version>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.3.3.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Main.class:
package com.mycompany.test_aop;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.EnableLoadTimeWeaving;
import org.springframework.context.annotation.aspectj.EnableSpringConfigured;
import org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver;
#SpringBootApplication
#EnableSpringConfigured
#EnableAspectJAutoProxy
#EnableLoadTimeWeaving
#ComponentScan(value = "com.mycompany.test_aop")
public class Main {
public static void main(String args[]) {
SpringApplication.run(Main.class, args);
}
#Bean
public InstrumentationLoadTimeWeaver loadTimeWeaver() throws Throwable {
InstrumentationLoadTimeWeaver loadTimeWeaver = new InstrumentationLoadTimeWeaver();
return loadTimeWeaver;
}
}
Web.java:
package com.mycompany.test_aop;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
#Controller
public class web {
#Autowired
Test t;
#RequestMapping(value = "/")
public #ResponseBody String root(){
System.out.println("...:::TEST CONTROLLER");
System.out.println("...:::TEST autowired in cotrnoller: "+t);
Test2 a = new Test2();
a.check();
return "HI!";
}
}
Test.java:
package com.mycompany.test_aop;
import org.springframework.stereotype.Service;
#Service
public class Test {
public void display() {
System.out.println("...:::TEST CLASS CALL DISPLAY");
}
}
Test2.java
package com.mycompany.test_aop;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
#Configurable
public class Test2 {
#Autowired
private Test t;
public Test2() {
System.out.println("...:::NEW");
}
public void check() {
System.out.println("...:::Check: "+t);
}
}
Webapp has different pom, addittional file app-servlet.xml and no main method:
Main.java
package com.mycompany.test_aop;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableLoadTimeWeaving;
import org.springframework.context.annotation.aspectj.EnableSpringConfigured;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
#EnableSpringConfigured
#EnableLoadTimeWeaving
#ComponentScan(value = "com.mycompany.test_aop")
#Configuration
#EnableWebMvc
public class Main extends WebMvcConfigurerAdapter {
}
app-servlet.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:default-servlet-handler/>
<context:annotation-config/>
<bean class="com.mycompany.test_aop.Main"/>
<mvc:annotation-driven>
</mvc:annotation-driven>
</beans>
By using Autowire Annotations.
#Autowired
Test2 a;
#RequestMapping(value = "/")
public #ResponseBody String root(){
System.out.println("...:::TEST CONTROLLER");
System.out.println("...:::TEST autowired in cotrnoller: "+t);
Test2 a = new Test2();//instead of this use autowired of test2
a.check();
return "HI!";
If you give thisTest2 a=new Test2();It will initiate with new Object then it will show only NULL

Spring #Autowired working without context:annotation-config [duplicate]

This question already has answers here:
Difference between <context:annotation-config> and <context:component-scan>
(15 answers)
Closed 3 years ago.
I've tested the behavior of auto wiring in case the context:annotation-config element is missing in the application context xml file. To my surprise it worked just the same.
So here is my question:
How come an AutowiredAnnotationBeanPostProcessor is registered in the ApplicationContext even though the context:annotation-config element is missing from the application context configuration file, or what else mechanism makes this configuration work?
I'm using Spring version 3.0.6.RELEASE
This is the project pom file:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven- v4_0_0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.samples.spring</groupId>
<artifactId>spring-utility</artifactId>
<version>1.0.0.CI-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Spring Utility</name>
<url>http://www.springframework.org</url>
<description>
<![CDATA[
This project is a minimal jar utility with Spring configuration.
]]>
</description>
<properties>
<maven.test.failure.ignore>true</maven.test.failure.ignore>
<spring.framework.version>3.0.6.RELEASE</spring.framework.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.framework.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.framework.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
This is the application context configuration file, with the context:annotation-config element commented out:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<description>Example configuration to get you started.</description>
<!-- context:annotation-config/ -->
<context:component-scan base-package="com.foo.ch04" />
</beans>
A MessageProvider, that will be used as collaborator by a dependent bean MessageRenderer
package com.foo.ch04.helloworld;
import org.springframework.stereotype.Service;
#Service("messageProvider")
public class HelloWorldMessageProvider implements MessageProvider {
public String getMessage() {
return "Hello, World!";
}
}
The MessageRenderer, whose dependency messageProvider gets auto-injected:
package com.foo.ch04.helloworld;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
#Service("messageRenderer")
public class StandardOutMessageRenderer implements MessageRenderer {
private MessageProvider messageProvider;
public void render() {
if (messageProvider == null) {
throw new RuntimeException(
"You must set the property messageProvider before rendering message.");
}
System.out.println(messageProvider.getMessage());
}
#Autowired
public void setMessageProvider(MessageProvider provider) {
messageProvider = provider;
}
public MessageProvider getMessageProvider() {
return messageProvider;
}
}
The test application loading the application context and testing the messageRenderer:
package com.foo.ch04.helloworld;
import org.springframework.context.support.GenericXmlApplicationContext;
public class DeclareSpringComponents {
public static void main(String[] args) {
GenericXmlApplicationContext context = new GenericXmlApplicationContext();
context.load("classpath:META-INF/spring/app-context-annotation.xml");
context.refresh();
MessageRenderer renderer = context.getBean("messageRenderer",
MessageRenderer.class);
renderer.render();
}
}
Even though the is missing in the application context configuration file, the message "Hello, World!" is written to stdout when the application is run.
The use of <context:component-scan /> implies annotation based configuration and as such specifying <context:annotation-config/> is redundant.
'context:annotation-config' This annotation-config tag is used to process the auto wired beans declared in the application context XML file. If the auto wired bean could be discovered using the scope of 'context:component-scan' tag then no need to use 'context:annotation-config' tag

Maven execution of single attached test

I'm relatively new to maven and have been struggling with attached tests, I've found a few articles here that have got me part of the way there but can't quite get that last little bit. Here is what I'm trying to do. I have 2 modules one that defines a set of interfaces and rudimentary test of those interfaces. The second module provides an implementation of the interface and I'd like to run the predefined test on it. I boiled it down to a simple example, here are the two projects:
interface
+ pom.xml
+ src
+ main
+ java
+ demo
+ Messenger.java
+ test
+ java
+ demo
+ MessengerTest.java
impl
+ pom.xml
+ src
+ main
+ java
+ demo
+ impl
+ MessengerImpl.java
+ test
+ resources
+ context.xml
The interface pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven- 4.0.0.xsd">
<groupId>demo</groupId>
<artifactId>interface</artifactId>
<version>1.0</version>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.2.2.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.14</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
The Messenger.java source:
package demo;
public interface Messenger {
String getMessage();
}
The MessengerTest.java source:
package demo;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import demo.Messenger;
public class MessengerTest {
private BeanFactory beanfactory;
#Before
public void setUp() throws Exception {
beanfactory = new ClassPathXmlApplicationContext("context.xml");
}
#Test
public final void testGetMessage() throws Exception {
final Messenger msngr = beanfactory.getBean(Messenger.class);
String msg = msngr.getMessage();
assertNotNull(msg);
assertTrue(msg.length() > 0);
}
}
Executing 'mvn install' appears to do the right thing creating interface-1.0.jar and interface-1.0-tests.jar in my local repository.
The implementation code is simple, the pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<groupId>demo</groupId>
<artifactId>impl</artifactId>
<version>1.0</version>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>demo</groupId>
<artifactId>interface</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>demo</groupId>
<artifactId>interface</artifactId>
<version>1.0</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
</dependencies>
</project>
The MessageImpl.java source:
package demo.impl;
import demo.Messenger;
public class MessengerImpl implements Messenger {
#Override
public String getMessage() {
return "Hello World";
}
}
And finally, the spring context file:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="MyMessenger" class="demo.impl.MessengerImpl"/>
</beans>
With all of this in place I execute 'mvn -Dtest=demo.MessengerTest test', and unfortunately it fails with "... No tests were executed!". So there is the problem.
Sorry, for being so long winded but I wanted to be fairly complete, any guidance would be greatly appreciated.
Surefire doesn't scan through the classpath when deciding what classes to run, so only tests defined in the same module are normally considered. It checks in target/classes in the impl project, doesn't see any tests, and ignores MessengerTest. You could define a test suite in the impl project that references the tests to run, or unzip the dependency into target/classes.

Resources