Fundamentally, you’re trying to replace a private field with an alternative implementation, which means you’d violate encapsulation. Your only other option is to restructure the class or method, to make it better-designed for testing.
There are a lot of short answers in the comments, so I’m aggregating them here (and adding a couple of my own) as Community Wiki. If you have any alternatives, please feel free to add them here.
Restructure the class
-
Create a setter for the field in question, or relax the field’s visibility.
-
Create a dependency-injecting override or static method that takes a DAO, and make the public instance method delegate to it. Test the more-flexible method instead.
public String myMethod() { return myMethod(dao); } String myMethod(Dao dao) { /* real implementation here */ }
-
Add a constructor overload or static factory method that replaces private fields for the sake of testing.
-
Fully structure the class for dependency injection. (Sotirios Delimanolis, EJK)
Note that some of these can be package-private for testing, if you put your tests in the same Java package (possibly in a separate source tree). In all cases, good names and documentation are helpful to make your intentions clear.
Violate encapsulation
- Use reflection to set private fields in the class. (kinbiko – see answer)
- Use PowerMockito to replace the
Dao
constructor with a mock of your choice. (Dave Newton)