Reputation: 31895
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?
Upvotes: 28
Views: 15011
Reputation: 1328
If you want to hide details (that are required for your tests) of your class, you could use lombok to easily generate an appropriate getter-Method with package-level access, which would allow reading (from test classes in same package) but prevent mutation (everywhere) of a certain field.
public class SimpleRetryStrategy implements RetryStrategy {
@Getter(AccessLevel.PACKAGE)
private final int maxRetries;
Upvotes: 0
Reputation: 7792
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
.
Upvotes: 28
Reputation: 8220
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
.
Upvotes: 5