Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can we test package-private class?

I am reading book Effective Java, in Item 13: Minimize the accessibility of classes and members, it mentioned that:

To facilitate testing, you may be tempted to make a class, interface, or member more accessible. This is fine up to a point. it is acceptable to make a private member of a public class package-private in order to test it, but it is not acceptable to raise the accessibility any higher than that. In other words, it is not acceptable to make a class, interface, or member a part of packages's exported API to facilitate testing.

I know we should encapsulate members, hiding information from clients, we can test them by accessing the class with setters and getters, but How should I understand make class package-private accessible, if so How to test it?

like image 955
Haifeng Zhang Avatar asked Feb 15 '17 17:02

Haifeng Zhang


People also ask

Can we test private methods in JUnit?

So whether you are using JUnit or SuiteRunner, you have the same four basic approaches to testing private methods: Don't test private methods. Give the methods package access. Use a nested test class.

Can we unit test private methods?

Unit Tests Should Only Test Public Methods The short answer is that you shouldn't test private methods directly, but only their effects on the public methods that call them. Unit tests are clients of the object under test, much like the other classes in the code that are dependent on the object.


2 Answers

Basically it means that your tester class should reside in the same package as your tested class. That would make your tested class and all package protected members and methods accessible to your testing class. The classes may be located under different roots: your tested class may be under src/main/java/myrootpackage/first/second/MyClass.java and your testing class may be located under src/test/java/myrootpackage/first/second/MyClassTester.java.

like image 127
Michael Gantman Avatar answered Oct 20 '22 10:10

Michael Gantman


I guess what the author means is that instead of

package my.package;

class TestableClass {
     private String property;
}

You can change the visibility to

package my.package;

class TestableClass {
    String property;
}

With the second implementation you can access the property from a test in the package my.package like

package my.package;

class TestableClassTest {
    // ...
}

At the same time, a subclass cannot access the property - that's the benefit comapred to protected.

like image 36
Michael Lihs Avatar answered Oct 20 '22 10:10

Michael Lihs