Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it bad practice to use Reflection in Unit testing? [duplicate]

During the last years I always thought that in Java, Reflection is widely used during Unit testing. Since some of the variables/methods which have to be checked are private, it is somehow necessary to read the values of them. I always thought that the Reflection API is also used for this purpose.

Last week i had to test some packages and therefore write some JUnit tests. As always i used Reflection to access private fields and methods. But my supervisor who checked the code wasn't really happy with that and told me that the Reflection API wasn't meant to use for such "hacking". Instead he suggested to modifiy the visibility in the production code.

Is it really bad practice to use Reflection? I can't really believe that-

Edit: I should have mentioned that i was required that all tests are in a separate package called test (so using protected visibilty e.g. wasn't a possible solution too)

like image 719
RoflcoptrException Avatar asked May 11 '10 13:05

RoflcoptrException


People also ask

What are two limitations of unit testing?

Limitations of Unit Testing Unit testing cannot detect integration or interfacing issues between two modules. It cannot catch complex errors in the system ranging from multiple modules. It cannot test non-functional attributes like usability, scalability, the overall performance of the system, etc.

What is reflection in unit testing?

Introduction. ReflectionTestUtils is a part of Spring Test Context framework. It is a collection for reflection-based utility methods used in a unit, and integration testing scenarios to set the non-public fields, invoke non-public methods, and inject dependencies.


2 Answers

IMHO Reflection should really only be a last resort, reserved for the special case of unit testing legacy code or an API you can't change. If you are testing your own code, the fact that you need to use Reflection means your design is not testable, so you should fix that instead of resorting to Reflection.

If you need to access private members in your unit tests, it usually means the class in question has an unsuitable interface, and/or tries to do too much. So either its interface should be revised, or some code should be extracted into a separate class, where those problematic methods / field accessors can be made public.

Note that using Reflection in general results in code which, apart from being harder to understand and maintain, is also more fragile. There are a whole set of errors which in the normal case would be detected by the compiler, but with Reflection they crop up as runtime exceptions only.

Update: as @tackline noted, this concerns only using Reflection within one's own test code, not the internals of the testing framework. JUnit (and probably all other similar frameworks) uses reflection to identify and call your test methods - this is a justified and localized use of reflection. It would be difficult or impossible to provide the same features and convenience without using Reflection. OTOH it is completely encapsulated within the framework implementation, so it does not complicate or compromise our own testing code.

like image 88
Péter Török Avatar answered Sep 21 '22 18:09

Péter Török


It is really bad to modify the visibility of a production API just for the sake of testing. That visibility is likely to be set to its current value for valid reasons and is not to be changed.

Using reflection for unit testing is mostly fine. Of course, you should design your classes for testability, so that less reflection is required.

Spring for example has ReflectionTestUtils. But its purpose is set mocks of dependencies, where spring was supposed to inject them.

The topic is deeper than "do & don't", and regards what should be tested - whether the internal state of the objects needs to be tested or not; whether we should afford questioning the design of the class under test; etc.

like image 45
Bozho Avatar answered Sep 18 '22 18:09

Bozho