Spring @Autowired fields - which access modifier, private or package-private?

I generally prefer having the field private and using setter injection:

public class MyClass {

    private MyService myService;

    @Autowired
    public void setMyService(MyService myService) {
        this.myService = myService;
    }
}   

allowing the service to be @Autowired, but set with a mocked instance for unit testing.


So both cases work fine, but which is more recommended, particularly with regards to testing?

I think the properties should be private:

@Autowired
private MyService myService;

As it is always good to have getter methods to provide access to the properties instead of allowing other classes to have direct access to them.

And for testing purposes, injection of mocks of private properties will work the same way as that of package-private properties.

For example, with Mockito, you can inject a mock of private MyService into MyClass as this:

public class MyClassTest {

    @Mock
    MyService service;

    @InjectMocks
    MyClass serv = new MyClass();

    @Before
    public void init() {
    MockitoAnnotations.initMocks(this);
    }
}

The first case also allows you to inject mocks depending on the framework. For example using the @InjectMocks annotation of Mockito. You also have ReflectionTestUtils.setField in Spring test, ...

I'm personally not too fond of modifying classes too much for testing purposes, so I would go for the first case. But at the end of the day this mostly depends on your preferred test framework.