Why cannot System.setProperty be used at Class level? - java

I had tried using System.setProperty in main method with no issues, but when I switched to TestNG as part of my Selenium learning, I realized we cannot write System.setProperty at Class level. It should be either at method level or be in a static block. I just want to understand what is the feature of Java that is compelling us to do this.
public class NewTest {
public String baseUrl = "http://newtours.demoaut.com/";
static {
System.setProperty("webdriver.chrome.driver","D:\\paths\\chromedriver.exe");
}
WebDriver driver = new ChromeDriver();
#Test
public void f1() {
...}
}
Writing this outside of static block shows compilation error like
"Multiple markers at this line, Syntax error"

I just want to understand what is the feature of Java that is compelling us to do this.
The 'feature of Java' is that you can only write methods and declarations at class level, and System.setProperty() is neither: it is a method call.

a basic class need method to perform any action
note - same way you can't call System.out.println("");

Calling System.setProperty() in a static block is occurring at the class level. What is perhaps surprising you is that this only happens once per program - the first time your NewTest class is referenced. static fields and blocks are guaranteed to be executed exactly once per JVM invocation, and that's a feature. If you want your code to be run more often than that you don't want to use static statements.
JUnit and similar testing frameworks provided dedicated mechanisms for running setup code before each class or method that's invoked. See #Before and #BeforeClass, along with this question for more specifics about how to implement this behavior in JUnit.
If #Before/#BeforeClass don't address your question please edit it with more context to clarify what you're trying to accomplish. Including code samples of what you've tried - and why it hasn't worked - is particularly helpful.

Related

How do you run a set of test classes from 1 class

Currently all my tests extend another class that has a #BeforeAll tag but I want this BeforeAll code to be run just once in total for the entirety of the tests instead of once per class
#BeforeAll
static void createWriter() throws IOException {
// create file to be writen to
}
#AfterAll
static void finishFile() throws IOException {
// end file and create high level metrics
}
#Override
public void testSuccess(ExtensionContext extensionContext, Throwable throwable) {
// override normal test execution finishes
}
You have to run test cases as a test suite. You can use testing framework "TestNG" to achieve this functionality.
Use annotations #BeforeSuite and #AfterSuite, which will execute once for multiple test classes.
Please check with this link for detailed information.
I am not aware of any built-in way of doing that. So the simple technical answer would be to use a static boolean flag that tells that method whether the method ran already (or not). Upon the first method execution, that flag gets toggled, and prevents further executions.
But the real answer is: you are probably going down the wrong rabbit hole. Having test classes extend a base class is more of an anti pattern, and to have a BeforeAll method that is either too expensive to be called repeatedly, or worse: not idempotent makes things worse. Unit tests should be simple and self explanatory (thus self contained). Inheritance and "run only once" directly violate that requirement.

JShell - How to add method to existing class without replacing this class?

tl;dr : How to add method to existing class without replacing this class?
Description:
When I run following command in JShell:
public class TestClass {}
following output is printed:
created class TestClass
Running this command once more gives following output:
modified class TestClass
Let's create class with one method, as below:
public class TestClass {
public static void testMethod1() {
System.out.println("In testMethod1");
}
}
It's worth to mention that the output is slightly different from previous class overwriting:
replaced class TestClass
Running testMethod1 ends successfully and In testMethod1 is printed in console.
Now I want to add new method to existing TestClass without loosing testMethod1. So I run following snippet:
public class TestClass {
public static void testMethod2() {
System.out.println("In testMethod2");
}
}
...and testMethod1 is lost, because whole TestClass has been replaced.
How can I add new method to existing class without overwriting it? What if I have written like 10 methods? Am I supposed to write down existing methods next to new method that I want to add to class?
Shouldn't JShell prompt user about class to be replaced in form of warning?
Any hints or help is appreciated.
JShell cannot do this and I do not think it would be what most people want. If you want to regularly merge into existing code, you probably want to use an editor that keeps the source code intact and compile your source from scratch. JShell would need to keep track of all kinds of source code information in addition to the compiled byte code to allow for what you want. For example, what would happen if you added a method that already was implemented as a bridge method as result of defining a generic method?
The reason the message differs with replaced or modified is because of JShells use of HotSwap which can only be applied when a class does not change its shape, i.e. declares the same methods and fields with the same signatures.
How can I add a new method to existing class without overwriting it?
You can perform this using the
/edit
which opens up a Jshell edit pad, where you can add your new method and Accept to update the class definition in your case. The jshell commands also illustrates several other attributes to edit multiple snippets using their name or id. Adding a screenshot for how to do this:
What if I have written like 10 methods? Am I supposed to write down existing methods next to new method that I want to add to class?
Such a use case seems more looking out for an IDE rather than the REPL based jshell and is clearly mentioned as a Non Goal on the JEP#222 jshell: The Java Shell (Read-Eval-Print Loop)
Out of scope are graphical interfaces and debugger support. The JShell API is intended to allow JShell functionality in IDEs and other
tools, but the jshell tool is not intended to be an IDE.
Shouldn't JShell prompt user about class to be replaced in form of warning?
Would second #Elliot as mentioned in the comments, Apparently it doesn't for now.
Though this sounds an interesting ask IMHO but would have to be equally weighed against the thoughts of implementing it, along with not bring down the performance of the tool. The answer by #Rafael provides a hint about maintaining such overhead.

what is the advantage of using #VisibleForTesting? [duplicate]

This question already has answers here:
How do I test a class that has private methods, fields or inner classes?
(58 answers)
Closed 5 years ago.
Who has a solution for that common need.
I have a class in my application.
some methods are public, as they are part of the api,
and some are private, as they for internal use of making the internal flow more readable
now, say I want to write a unit test, or more like an integration test, which will be located in a different package, which will be allowed to call this method, BUT, I want that normal calling to this method will not be allowed if you try to call it from classes of the application itself
so, I was thinking about something like that
public class MyClass {
public void somePublicMethod() {
....
}
#PublicForTests
private void somePrivateMethod() {
....
}
}
The annotation above will mark the private method as "public for tests"
which means, that compilation and runtime will be allowed for any class which is under the test... package , while compilation and\or runtime will fail for any class which is not under the test package.
any thoughts?
is there an annotation like this?
is there a better way to do this?
it seems that the more unit tests you write, to more your inforced to break your encapsulation...
The common way is to make the private method protected or package-private and to put the unit test for this method in the same package as the class under test.
Guava has a #VisibleForTesting annotation, but it's only for documentation purposes.
If your test coverage is good on all the public method inside the tested class, the privates methods called by the public one will be automatically tested since you will assert all the possible case.
The JUnit Doc says:
Testing private methods may be an indication that those methods should be moved into another class to promote reusability.
But if you must...
If you are using JDK 1.3 or higher, you can use reflection to subvert the access control mechanism with the aid of the PrivilegedAccessor. For details on how to use it, read this article.
Consider using interfaces to expose the API methods, using factories or DI to publish the objects so the consumers know them only by the interface. The interface describes the published API. That way you can make whatever you want public on the implementation objects and the consumers of them see only those methods exposed through the interface.
dp4j has what you need. Essentially all you have to do is add dp4j to your classpath and whenever a method annotated with #Test (JUnit's annotation) calls a method that's private it will work (dp4j will inject the required reflection at compile-time). You may also use dp4j's #TestPrivates annotation to be more explicit.
If you insist on also annotating your private methods you may use Google's #VisibleForTesting annotation.
An article on Testing Private Methods lays out some approaches to testing private code. using reflection puts extra burden on the programmer to remember if refactoring is done, the strings aren't automatically changed, but I think it's the cleanest approach.
Or you can extract this method to some strategy object. In this case you can easily test extracted class and don't make method public or some magic with reflection/bytecode.
Okay, so here we have two things that are being mixed. First thing, is when you need to mark something to be used only on test, which I agree with #JB Nizet, using the guava annotation would be good.
A different thing, is to test private methods. Why should you test private methods from the outside? I mean.. You should be able to test the object by their public methods, and at the end that its behavior. At least, that we are doing and trying to teach to junior developers, that always try to test private methods (as a good practice).
I am not aware of any such annotation, however the following may be of value: unit testing private methods
or the following: JMockit
You can't do this, since then how could you even compile your tests? The compiler won't take the annotation into account.
There are two general approaches to this
The first is to use reflection to access the methods anyway
The second is to use package-private instead of private, then have your tests in the same package (but in a different module). They will essentially be private to other code, but your tests will still be able to access them.
Of course, if you do black-box testing, you shouldn't be accessing the private members anyway.
We recently released a library that helps a lot to access private fields, methods and inner classes through reflection : BoundBox
For a class like
public class Outer {
private static class Inner {
private int foo() {return 2;}
}
}
It provides a syntax like :
Outer outer = new Outer();
Object inner = BoundBoxOfOuter.boundBox_new_Inner();
new BoundBoxOfOuter.BoundBoxOfInner(inner).foo();
The only thing you have to do to create the BoundBox class is to write #BoundBox(boundClass=Outer.class) and the BoundBoxOfOuter class will be instantly generated.
As much as I know there is no annotation like this. The best way is to use reflection as some of the others suggested. Look at this post:
How do I test a class that has private methods, fields or inner classes?
You should only watch out on testing the exception outcome of the method. For example: if u expect an IllegalArgumentException, but instead you'll get "null" (Class:java.lang.reflect.InvocationTargetException).
A colegue of mine proposed using the powermock framework for these situations, but I haven't tested it yet, so no idea what exactly it can do. Although I have used the Mockito framework that it is based upon and thats a good framework too (but I think doesn't solve the private method exception issue).
It's a great idea though having the #PublicForTests annotation.
Cheers!
I just put the test in the class itself by making it an inner class:
https://rogerkeays.com/how-to-unit-test-private-methods

Warning: main methods should not be directly called

I currently work on a Java project which has many main methods. Now, I do some refactoring, which affects all main methods. However, some of the main methods are actually called directly from other methods. I think this is bad style and it actually makes the refactoring harder. Thus, I want to be able to identify all places where a main method is called. Currently, I use my IDE tools to find all references to a given main method, however this is tedious and it is easy to forget to check this for one of the main methods.
My question is, whether there is some checkstyle rule or Eclipse compiler warnings setting that produces a warning whenever a main method is called directly. I was unable to find one.
If you are concerned that people may have formatted the "main" methods in variety of ways, and that you may miss some of them when you use "pattern matching" ...
Could "javap -public MyClass.class" work for you? When I tried it on ...
public class Main1 {
public
static
void
main
(
String
[]
args
)
{
System.out.println("Main1: Hello World");
}
}
It produced the following output:
Compiled from "Main1.java"
public class Main1 {
public Main1();
public static void main(java.lang.String[]);
}
Admittedly, it doesn't 'detect' if this 'main' is calling another 'main', it will be helpful just in finding all the 'main's.
Source derived from Post: Java Program to disassemble Java Byte Code
As #Jeutnarg suggested in the comments:
[...] you could use Eclipse's Java search. Search for 'main', only searching for 'Method' with Limit to 'References' with Search in 'Sources' with a scope of your project.
This is what I ended up doing and it actually worked much better than I expected.

How to test and mock 2 private methods in the same class in Java? [duplicate]

How do I use JUnit to test a class that has internal private methods, fields or nested classes?
It seems bad to change the access modifier for a method just to be able to run a test.
If you have somewhat of a legacy Java application, and you're not allowed to change the visibility of your methods, the best way to test private methods is to use reflection.
Internally we're using helpers to get/set private and private static variables as well as invoke private and private static methods. The following patterns will let you do pretty much anything related to the private methods and fields. Of course, you can't change private static final variables through reflection.
Method method = TargetClass.getDeclaredMethod(methodName, argClasses);
method.setAccessible(true);
return method.invoke(targetObject, argObjects);
And for fields:
Field field = TargetClass.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, value);
Notes:
TargetClass.getDeclaredMethod(methodName, argClasses) lets you look into private methods. The same thing applies for
getDeclaredField.
The setAccessible(true) is required to play around with privates.
The best way to test a private method is via another public method. If this cannot be done, then one of the following conditions is true:
The private method is dead code
There is a design smell near the class that you are testing
The method that you are trying to test should not be private
When I have private methods in a class that are sufficiently complicated that I feel the need to test the private methods directly, that is a code smell: my class is too complicated.
My usual approach to addressing such issues is to tease out a new class that contains the interesting bits. Often, this method and the fields it interacts with, and maybe another method or two can be extracted in to a new class.
The new class exposes these methods as 'public', so they're accessible for unit testing. The new and old classes are now both simpler than the original class, which is great for me (I need to keep things simple, or I get lost!).
Note that I'm not suggesting that people create classes without using their brain! The point here is to use the forces of unit testing to help you find good new classes.
I have used reflection to do this for Java in the past, and in my opinion it was a big mistake.
Strictly speaking, you should not be writing unit tests that directly test private methods. What you should be testing is the public contract that the class has with other objects; you should never directly test an object's internals. If another developer wants to make a small internal change to the class, which doesn't affect the classes public contract, he/she then has to modify your reflection based test to ensure that it works. If you do this repeatedly throughout a project, unit tests then stop being a useful measurement of code health, and start to become a hindrance to development, and an annoyance to the development team.
What I recommend doing instead is using a code coverage tool, such as Cobertura, to ensure that the unit tests you write provide decent coverage of the code in private methods. That way, you indirectly test what the private methods are doing, and maintain a higher level of agility.
From this article: Testing Private Methods with JUnit and SuiteRunner (Bill Venners), you basically have 4 options:
Don't test private methods.
Give the methods package access.
Use a nested test class.
Use reflection.
Generally a unit test is intended to exercise the public interface of a class or unit. Therefore, private methods are implementation detail that you would not expect to test explicitly.
Just two examples of where I would want to test a private method:
Decryption routines - I would not
want to make them visible to anyone to see just for
the sake of testing, else anyone can
use them to decrypt. But they are
intrinsic to the code, complicated,
and need to always work (the obvious exception is reflection which can be used to view even private methods in most cases, when SecurityManager is not configured to prevent this).
Creating an SDK for community
consumption. Here public takes on a
wholly different meaning, since this
is code that the whole world may see
(not just internal to my application). I put
code into private methods if I don't
want the SDK users to see it - I
don't see this as code smell, merely
as how SDK programming works. But of
course I still need to test my
private methods, and they are where
the functionality of my SDK actually
lives.
I understand the idea of only testing the "contract". But I don't see one can advocate actually not testing code—your mileage may vary.
So my trade-off involves complicating the JUnit tests with reflection, rather than compromising my security and SDK.
The private methods are called by a public method, so the inputs to your public methods should also test private methods that are called by those public methods. When a public method fails, then that could be a failure in the private method.
In the Spring Framework you can test private methods using this method:
ReflectionTestUtils.invokeMethod()
For example:
ReflectionTestUtils.invokeMethod(TestClazz, "createTest", "input data");
Another approach I have used is to change a private method to package private or protected then complement it with the #VisibleForTesting annotation of the Google Guava library.
This will tell anybody using this method to take caution and not access it directly even in a package. Also a test class need not be in same package physically, but in the same package under the test folder.
For example, if a method to be tested is in src/main/java/mypackage/MyClass.java then your test call should be placed in src/test/java/mypackage/MyClassTest.java. That way, you got access to the test method in your test class.
To test legacy code with large and quirky classes, it is often very helpful to be able to test the one private (or public) method I'm writing right now.
I use the junitx.util.PrivateAccessor-package for Java. It has lots of helpful one-liners for accessing private methods and private fields.
import junitx.util.PrivateAccessor;
PrivateAccessor.setField(myObjectReference, "myCrucialButHardToReachPrivateField", myNewValue);
PrivateAccessor.invoke(myObjectReference, "privateMethodName", java.lang.Class[] parameterTypes, java.lang.Object[] args);
Having tried Cem Catikkas' solution using reflection for Java, I'd have to say his was a more elegant solution than I have described here. However, if you're looking for an alternative to using reflection, and have access to the source you're testing, this will still be an option.
There is possible merit in testing private methods of a class, particularly with test-driven development, where you would like to design small tests before you write any code.
Creating a test with access to private members and methods can test areas of code which are difficult to target specifically with access only to public methods. If a public method has several steps involved, it can consist of several private methods, which can then be tested individually.
Advantages:
Can test to a finer granularity
Disadvantages:
Test code must reside in the same
file as source code, which can be
more difficult to maintain
Similarly with .class output files, they must remain within the same package as declared in source code
However, if continuous testing requires this method, it may be a signal that the private methods should be extracted, which could be tested in the traditional, public way.
Here is a convoluted example of how this would work:
// Import statements and package declarations
public class ClassToTest
{
private int decrement(int toDecrement) {
toDecrement--;
return toDecrement;
}
// Constructor and the rest of the class
public static class StaticInnerTest extends TestCase
{
public StaticInnerTest(){
super();
}
public void testDecrement(){
int number = 10;
ClassToTest toTest= new ClassToTest();
int decremented = toTest.decrement(number);
assertEquals(9, decremented);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(StaticInnerTest.class);
}
}
}
The inner class would be compiled to ClassToTest$StaticInnerTest.
See also: Java Tip 106: Static inner classes for fun and profit
As others have said... don't test private methods directly. Here are a few thoughts:
Keep all methods small and focused (easy to test, easy to find what is wrong)
Use code coverage tools. I like Cobertura (oh happy day, it looks like a new version is out!)
Run the code coverage on the unit tests. If you see that methods are not fully tested add to the tests to get the coverage up. Aim for 100% code coverage, but realize that you probably won't get it.
If using Spring, ReflectionTestUtils provides some handy tools that help out here with minimal effort. For example, to set up a mock on a private member without being forced to add an undesirable public setter:
ReflectionTestUtils.setField(theClass, "theUnsettableField", theMockObject);
Private methods are consumed by public ones. Otherwise, they're dead code. That's why you test the public method, asserting the expected results of the public method and thereby, the private methods it consumes.
Testing private methods should be tested by debugging before running your unit tests on public methods.
They may also be debugged using test-driven development, debugging your unit tests until all your assertions are met.
I personally believe it is better to create classes using TDD; creating the public method stubs, then generating unit tests with all the assertions defined in advance, so the expected outcome of the method is determined before you code it. This way, you don't go down the wrong path of making the unit test assertions fit the results. Your class is then robust and meets requirements when all your unit tests pass.
If you're trying to test existing code that you're reluctant or unable to change, reflection is a good choice.
If the class's design is still flexible, and you've got a complicated private method that you'd like to test separately, I suggest you pull it out into a separate class and test that class separately. This doesn't have to change the public interface of the original class; it can internally create an instance of the helper class and call the helper method.
If you want to test difficult error conditions coming from the helper method, you can go a step further. Extract an interface from the helper class, add a public getter and setter to the original class to inject the helper class (used through its interface), and then inject a mock version of the helper class into the original class to test how the original class responds to exceptions from the helper. This approach is also helpful if you want to test the original class without also testing the helper class.
Testing private methods breaks the encapsulation of your class because every time you change the internal implementation you break client code (in this case, the tests).
So don't test private methods.
The answer from JUnit.org FAQ page:
But if you must...
If you are using JDK 1.3 or higher, you can use reflection to subvert
the access control mechanism with the aid of the PrivilegedAccessor.
For details on how to use it, read this article.
If you are using JDK 1.6 or higher and you annotate your tests with
#Test, you can use Dp4j to inject reflection in your test methods. For
details on how to use it, see this test script.
P.S. I'm the main contributor to Dp4j. Ask me if you need help. :)
If you want to test private methods of a legacy application where you can't change the code, one option for Java is jMockit, which will allow you to create mocks to an object even when they're private to the class.
PowerMockito is made for this.
Use a Maven dependency:
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-core</artifactId>
<version>2.0.7</version>
<scope>test</scope>
</dependency>
Then you can do
import org.powermock.reflect.Whitebox;
...
MyClass sut = new MyClass();
SomeType rval = Whitebox.invokeMethod(sut, "myPrivateMethod", params, moreParams);
I tend not to test private methods. There lies madness. Personally, I believe you should only test your publicly exposed interfaces (and that includes protected and internal methods).
If you're using JUnit, have a look at junit-addons. It has the ability to ignore the Java security model and access private methods and attributes.
Here is my generic function to test private fields:
protected <F> F getPrivateField(String fieldName, Object obj)
throws NoSuchFieldException, IllegalAccessException {
Field field =
obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
return (F)field.get(obj);
}
Please see below for an example;
The following import statement should be added:
import org.powermock.reflect.Whitebox;
Now you can directly pass the object which has the private method, method name to be called, and additional parameters as below.
Whitebox.invokeMethod(obj, "privateMethod", "param1");
I would suggest you refactoring your code a little bit. When you have to start thinking about using reflection or other kind of stuff, for just testing your code, something is going wrong with your code.
You mentioned different types of problems. Let's start with private fields. In case of private fields I would have added a new constructor and injected fields into that. Instead of this:
public class ClassToTest {
private final String first = "first";
private final List<String> second = new ArrayList<>();
...
}
I'd have used this:
public class ClassToTest {
private final String first;
private final List<String> second;
public ClassToTest() {
this("first", new ArrayList<>());
}
public ClassToTest(final String first, final List<String> second) {
this.first = first;
this.second = second;
}
...
}
This won't be a problem even with some legacy code. Old code will be using an empty constructor, and if you ask me, refactored code will look cleaner, and you'll be able to inject necessary values in test without reflection.
Now about private methods. In my personal experience when you have to stub a private method for testing, then that method has nothing to do in that class. A common pattern, in that case, would be to wrap it within an interface, like Callable and then you pass in that interface also in the constructor (with that multiple constructor trick):
public ClassToTest() {
this(...);
}
public ClassToTest(final Callable<T> privateMethodLogic) {
this.privateMethodLogic = privateMethodLogic;
}
Mostly all that I wrote looks like it's a dependency injection pattern. In my personal experience it's really useful while testing, and I think that this kind of code is cleaner and will be easier to maintain. I'd say the same about nested classes. If a nested class contains heavy logic it would be better if you'd moved it as a package private class and have injected it into a class needing it.
There are also several other design patterns which I have used while refactoring and maintaining legacy code, but it all depends on cases of your code to test. Using reflection mostly is not a problem, but when you have an enterprise application which is heavily tested and tests are run before every deployment everything gets really slow (it's just annoying and I don't like that kind of stuff).
There is also setter injection, but I wouldn't recommended using it. I'd better stick with a constructor and initialize everything when it's really necessary, leaving the possibility for injecting necessary dependencies.
A private method is only to be accessed within the same class. So there is no way to test a “private” method of a target class from any test class. A way out is that you can perform unit testing manually or can change your method from “private” to “protected”.
And then a protected method can only be accessed within the same package where the class is defined. So, testing a protected method of a target class means we need to define your test class in the same package as the target class.
If all the above does not suits your requirement, use the reflection way to access the private method.
As many above have suggested, a good way is to test them via your public interfaces.
If you do this, it's a good idea to use a code coverage tool (like EMMA) to see if your private methods are in fact being executed from your tests.
Today, I pushed a Java library to help testing private methods and fields. It has been designed with Android in mind, but it can really be used for any Java project.
If you got some code with private methods or fields or constructors, you can use BoundBox. It does exactly what you are looking for.
Here below is an example of a test that accesses two private fields of an Android activity to test it:
#UiThreadTest
public void testCompute() {
// Given
boundBoxOfMainActivity = new BoundBoxOfMainActivity(getActivity());
// When
boundBoxOfMainActivity.boundBox_getButtonMain().performClick();
// Then
assertEquals("42", boundBoxOfMainActivity.boundBox_getTextViewMain().getText());
}
BoundBox makes it easy to test private/protected fields, methods and constructors. You can even access stuff that is hidden by inheritance. Indeed, BoundBox breaks encapsulation. It will give you access to all that through reflection, but everything is checked at compile time.
It is ideal for testing some legacy code. Use it carefully. ;)
First, I'll throw this question out: Why do your private members need isolated testing? Are they that complex, providing such complicated behaviors as to require testing apart from the public surface? It's unit testing, not 'line-of-code' testing. Don't sweat the small stuff.
If they are that big, big enough that these private members are each a 'unit' large in complexity—consider refactoring such private members out of this class.
If refactoring is inappropriate or infeasible, can you use the strategy pattern to replace access to these private member functions / member classes when under unit test? Under unit test, the strategy would provide added validation, but in release builds it would be simple passthrough.
I want to share a rule I have about testing which particularly is related to this topic:
I think that you should never adapt production code in order to
indulge easer writing of tests.
There are a few suggestions in other posts saying you should adapt the original class in order to test a private method - please red this warning first.
If we change the accessibility of a method/field to package private or protected, just in order to have it accessible to tests, then we defeat the purpose of existence of private access directive.
Why should we have private fields/methods/classes at all when we want to have test-driven development? Should we declare everything as package private, or even public then, so we can test without any effort?—I don't think so.
From another point of view: Tests should not burden performance and execution of the production application.
If we change production code just for the sake of easier testing, that may burden performance and the execution of the application in some way.
If someone starts to change private access to package private, then a developer may eventually come up to other "ingenious ideas" about adding even more code to the original class. This would make additional noise to readability and can burden the performance of the application.
With changing of a private access to some less restrictive, we are opening the possibility to a developer for misusing the new situation in the future development of the application. Instead of enforcing him/her to develop in the proper way, we are tempting him/her with new possibilities and giving him ability to make wrong choices in the future.
Of course there might be a few exceptions to this rule, but with clear understanding, what is the rule and what is the exception? We need to be absolutely sure we know why that kind of exception is introduced.

Categories