3

We have a standard Spring test class which loads an application context:

@ContextConfiguration(locations = {"classpath:app-context.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
public class AppTest {
   ...
}

The XML context uses standard placeholders e.g.: ${key} When the full application is run normally (not as a test), the main class will load the application context as follows so that the command line arguments are seen by Spring :

PropertySource ps = new SimpleCommandLinePropertySource(args);
context.getEnvironment().getPropertySources().addLast(ps);
context.load("classpath:META-INF/app-context.xml");
context.refresh();
context.start();

When running the Spring test, what code needs to be added to ensure that program arguments (e.g. --key=value): are passed from the IDE (in our case Eclipse) into the application context?

Thanks

Andrei Stefan
  • 51,654
  • 6
  • 98
  • 89
user1052610
  • 4,440
  • 13
  • 50
  • 101

1 Answers1

4

I don't think this is possible, not because of Spring, see this other question on SO with an explanation:

If you decide to use JVM arguments (-Dkey=value format) in Eclipse instead, it's easy in Spring to use those values:

import org.springframework.beans.factory.annotation.Value;

@ContextConfiguration(locations = {"classpath:app-context.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
public class AppTest {
   
    @Value("#{systemProperties[key]}")
    private String argument1;

    ...

}

Or, without @Value and just using a property placeholder:

@ContextConfiguration(locations = {"classpath:META-INF/spring/test-app-context.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
public class ExampleConfigurationTests {
    
    @Autowired
    private Service service;

    @Test
    public void testSimpleProperties() throws Exception {
        System.out.println(service.getMessage());
    }
    
}

where test-app-context.xml is

<bean class="com.foo.bar.ExampleService">
    <property name="arg" value="${arg1}" />
</bean>

<context:property-placeholder />

and ExampleService is:

@Component
public class ExampleService implements Service {
    
    private String arg;
    
    public String getArg() {
        return arg;
    }

    public void setArg(String arg) {
        this.arg = arg;
    }

    public String getMessage() {
        return arg; 
    }
}

and the argument passed to the test is a VM argument (specified like -Darg1=value1) and not a Program argument.

Both in Eclipse accessed with Right-Click on the test class -> Run As -> Run Configurations -> JUnit -> Arguments tab -> VM Arguments.

Manuel Jordan
  • 15,253
  • 21
  • 95
  • 158
Andrei Stefan
  • 51,654
  • 6
  • 98
  • 89
  • The problem with that I think is that the while it allows the test program to get the variables passeed in using -D, they will not be loaded into the Spring context. – user1052610 Jul 31 '14 at 10:39
  • Does not work. The first thing the Spring test will do is load the app-context.xml. Spring will then throw an IllegalStateException as one of the ${} placeholder variables will not have been defined. Declaring the variables themselves in the test itself using @Value therefore does not help. – user1052610 Jul 31 '14 at 11:12
  • That's strange. Works for me. I've updated my answer with another code sample. – Andrei Stefan Jul 31 '14 at 11:22
  • Thanks Andrei. Problem was thst I was passing in args using 'program arguments', and not VM arguments – user1052610 Jul 31 '14 at 11:53