I could find many questions/answers on why a method should not make it public. but I could not find anything specific to "default" in Java.
-
2Unit tests should be against the API of your unit. If that API is actually a package-private API then you should test that too - there’s many reasons for an API to be restricted - utility classes for example. But elevating an internal method just to test it smells of poor design, a class not designed for testing. Acceptable in legacy code, not in new code. – Boris the Spider Apr 15 '21 at 06:03
2 Answers
'default', i.e., the absence of a modifier, means package private in Java. Only classes in the same package can access it. Sometimes it is desirable to test an internal method meant for private use of that class in a unit test separate from the rest of that class in order to cover all code paths with clear, concise, and simple tests. When you do this (and the result is cleaner test code that can be maintained with more ease) it is fine to mark that method as package private.
This is not an uncommon strategy. Because the only classes who can use this method must reside in the same package, you still have plenty of control over its use.
Personally I would recommend only doing this for static
utility methods that do not depend on the state of their parent class. It is also a very useful technique for testing static methods in abstract classes.
Note that in some cases the need to test private methods may point to the need to break out that part of the class into a separate class instead. This discussion shows some of the common standpoints varying from strict OOP adherence to pragmatism. You often have the possibility to break out that method and make it into a proper public static utility, but that doesn't always make sense, and it doesn't necessarily lead to easier maintained code.

- 1,448
- 15
- 24
UnitTests are not about testing code, they are about testing public observable behavior, that is: return values and communication with dependencies.
Public observable does not necessarily imply public
methods but usually is. We simply test the Methods that other code would call when using the current unit as dependency.
Non public methods (that are not meant to be called by other code) are implementation detail that contributes to the units behavior. Therefore they are testes implicitly.
Keep in mind, that a unit is not connected to a class or a method. It might even be a group of classes behind a single class acting as "entry point". A unit is all the code that may change for the same (non technical) reason, a change in the business requirements.
The point here is that implementation details may change while the desired behavior (and thus the UnitTest) does not change. We do such changes to improve the code design (resolve code duplication, apply design patterns and alike). We call them refactoring (This is the third phase in the Test Driven Developement micro cycle). Such a refactoring is exactly the time when we need UnitTest most since when we not change them then they guarantee that the desired behavior of the tested code still exist.

- 15,071
- 2
- 27
- 51