How do I mock an autowired @Value field in Spring with Mockito?

Solution 1:

You can use the magic of Spring's ReflectionTestUtils.setField in order to avoid making any modifications whatsoever to your code.

The comment from Michał Stochmal provides an example:

use ReflectionTestUtils.setField(bean, "fieldName", "value"); before invoking your bean method during test.

Check out this tutorial for even more information, although you probably won't need it since the method is very easy to use

UPDATE

Since the introduction of Spring 4.2.RC1 it is now possible to set a static field without having to supply an instance of the class. See this part of the documentation and this commit.

Solution 2:

It was now the third time I googled myself to this SO post as I always forget how to mock an @Value field. Though the accepted answer is correct, I always need some time to get the "setField" call right, so at least for myself I paste an example snippet here:

Production class:

@Value("#{myProps[‘some.default.url']}")
private String defaultUrl;

Test class:

import org.springframework.test.util.ReflectionTestUtils;

ReflectionTestUtils.setField(instanceUnderTest, "defaultUrl", "http://foo");
// Note: Don't use MyClassUnderTest.class, use the instance you are testing itself
// Note: Don't use the referenced string "#{myProps[‘some.default.url']}", 
//       but simply the FIELDs name ("defaultUrl")

Solution 3:

You can use this magic Spring Test annotation :

@TestPropertySource(properties = { "my.spring.property=20" }) 

see org.springframework.test.context.TestPropertySource

For example, this is the test class :

@ContextConfiguration(classes = { MyTestClass.Config.class })
@TestPropertySource(properties = { "my.spring.property=20" })
public class MyTestClass {

  public static class Config {
    @Bean
    MyClass getMyClass() {
      return new MyClass ();
    }
  }

  @Resource
  private MyClass myClass ;

  @Test
  public void myTest() {
   ...

And this is the class with the property :

@Component
public class MyClass {

  @Value("${my.spring.property}")
  private int mySpringProperty;
   ...

Solution 4:

You can also mock your property configuration into your test class

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({ "classpath:test-context.xml" })
public class MyTest 
{ 
   @Configuration
   public static class MockConfig{
       @Bean
       public Properties myProps(){
             Properties properties = new Properties();
             properties.setProperty("default.url", "myUrl");
             properties.setProperty("property.value2", "value2");
             return properties;
        }
   }
   @Value("#{myProps['default.url']}")
   private String defaultUrl;

   @Test
   public void testValue(){
       Assert.assertEquals("myUrl", defaultUrl);
   }
}