Resolve Spring @Value expression in JUnit tests

Bernhard picture Bernhard · Jan 2, 2014 · Viewed 13.2k times · Source

Here's a snippet of a Spring bean:

@Component
public class Bean {

    @Value("${bean.timeout:60}")
    private Integer timeout;

    // ...
}

Now I want to test this bean with a JUnit test. I'm therefore using the SpringJUnit4ClassRunner and the ContextConfiguration annotation.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class BeanTest {

    @Autowired
    private Bean bean;

    // tests ...

    @Configuration
    public static class SpringConfiguration {
        @Bean
        public Bean bean() {
            return new Bean();
        }
    }
}

Unfortunately the SpringJUnit4ClassRunner can't resolve the @Value expression, even though a default value is supplied (a NumberFormatException is thrown). It seems that the runner isn't even able to parse the expression.

Is something missing in my test?

Answer

nobeh picture nobeh · Jan 2, 2014

Your test @Configuration class is missing an instance of PropertyPlaceholderConfigurer and that's why Spring does not know how to resolve those expressions; add a bean like the following to your SpringConfiguration class

@org.springframework.context.annotation.Bean
public static PropertyPlaceholderConfigurer propertyPlaceholderConfigurer() {
    PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
    ppc.setIgnoreResourceNotFound(true);
    return ppc;
}

and move it to a separate class and use

@ContextConfiguration(classes=SpringConfiguration.class)

to be more specific when running your test.