Spring value injection in mockito

Tags: , , , ,



I’m trying to write test class for the following method

public class CustomServiceImpl implements CustomService {
    @Value("#{myProp['custom.url']}")
    private String url;
    @Autowire
    private DataService dataService;

I’m using the injected url value in one of the methods in the class. To test this i’ve written a junit class

@RunWith(MockitoJUnitRunner.class)
@ContextConfiguration(locations = { "classpath:applicationContext-test.xml" })
public CustomServiceTest{
    private CustomService customService;
    @Mock
    private DataService dataService;
    @Before
    public void setup() {
        customService = new CustomServiceImpl();
        Setter.set(customService, "dataService", dataService);
    }    
    ...
}

public class Setter {
    public static void set(Object obj, String fieldName, Object value) throws Exception {
        Field field = obj.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        field.set(obj, value);
    }
}

In applicationContext-test.xml I’m loading the property file using

    <util:properties id="myProp" location="myProp.properties"/>

But the url value is not getting loaded in the CustomService on running the test. I was wondering if there is anyway to get this done.

Thanks

Answer

You can autowire into a mutator (setter), rather than just annotating the private field. Then you can use that setter from your test class as well. No need to make it public, package private will do as Spring can still access it, but otherwise only your test can get in there (or other code in the same package).

@Value("#{myProp['custom.url']}")
String setUrl( final String url ) {
    this.url  = url;
}

I’m not a fan of autowiring differently (compared to my codebase) just for testing, but the alternative of changing the class under test, from the test, is simply unholy.



Source: stackoverflow