There are different opinions on the meaningfulness of testing of private methods, e.g., here and here. I personally think it makes sense, the question is how to do it properly.
In C++ you can use a #define
hack or make the test class friend
, in C# there's the InternalsVisibleToAttribute, but in Java we either have to use reflection or to make them "visible for testing" and annotate them as such in order to make the intent clear. The disadvantages of both should be quite clear.
I think there should be something better. Starting with
public class Something {
private int internalSecret() {
return 43;
}
}
it would be nice to be able to call private methods in the test code like
@MakeVisibleForTesting Something something = new Something();
Assert.assertEquals(43, something.internalSecret());
Here the annotation would silently convert all calls to private methods of something
using reflection. I wonder if Lombok could do it (and will ask the authors).
It's quite possible that doing that much magic proves too complicated, and in any case it'll take some time, so I'm looking for some alternative. Maybe annotating the class under test with something like @Decapsulate
and using an annotation processor to generate a class Decapsulated_Something
looking like
public class Decapsulated_Something {
public Decapsulated_Something(Something delegate) {
this.delegate = delegate
}
public boolean internalSecret() {
// call "delegate.internalSecret()" using reflection
}
...
}
which would allow to use
Decapsulated_Something something = new Decapsulated_Something(new Something());
Assert.assertEquals(43, something.internalSecret());
I don't have much experience with annotation processing, so I ask first here:
- How complicated is this to implement?
- What did I forget?
- What do you think about it in general?