I understand we shouldn't test private methods/variables since that's an implementation detail, but I'm confused about the most reliable approach for mocking private variables/fields.
I had been relying on org.mockito.internal.util.reflection.Whitebox
but this no longer works with Mockito 2.6.2. The answer here suggests implementing the setInternalState
functionality of Whitebox - but I've noticed that org.powermock.reflect.Whitebox
still works and isn't within an internal
package. I don't want to rely heavily on it in my test suite only to have it break in a later PowerMock version. Is this reflection susceptible to breaking? Does it break encapsulation?
This answer instead says to inject the mock by adding a setter. But if the class I'm testing has 20+ private fields and I have to mock each of them in one test or another, this means I need to create setters for each? Wouldn't this essentially break encapsulation of my class (SUT)? Not to mention clutter up my class with ugly setters.
There also seems to be @RunWith(MockitoJUnitRunner.class)
to inject mocks as shown here but that post is 4 years old and I wasn't getting the same instant solution as with WhiteBox. I'd prefer not to have to use a DI framework if I don't have to. What is the most reliable way to mock private variables/fields?
Example:
public class ClassA() {
private PerformStats performStats;
private DataModel dataModel;
private String address;
private int age;
public ClassA() {
//... initializers
}
public void someMethod() {
age = dataModel.getAge(); // I want to used a mock dataModel here
}
}
I could use Whitebox.setInternalState(ClassA, "dataModel", dataModel);
in my test but I don't know if this is reliable long-term, or even recommended. Adding a setter for each field seems superfluous, and I'm unclear of its effect on encapsulation. What is the most reliable approach?
Aucun commentaire:
Enregistrer un commentaire