Java developers always use private access level for methods which are not used outside of this class. There are known benefits of doing so but from other side we increase complexity of unit tests. In most of cases our code is not used by any other services/APIs and we actually don't care of 'private' benefits. But what I believe we do care is to create readable simple unit tests. Considering this, why do not create all methods in class as 'package-private' by default and make them 'private' only in case when we really need this?
-
1What do you mean by "we increase unit test complexity"? – BackSlash Dec 02 '17 at 15:30
-
1You only increase unit-test complexity if you're writing tests of the private methods, which is generally not useful. Instead, write tests of the non-private methods that *use* them. No need to change tests just because you changed the internal implementation of the class. – T.J. Crowder Dec 02 '17 at 15:34
-
When you write tests which will cover private methods you will need to do it using open/accessible methods. This is what I mean saying "increase complexity of unit tests". – Aliaksei Yatsau Dec 02 '17 at 17:41
1 Answers
Why private access for methods is more preferable than package-private?
I would not say that it is preferable.
Both practices are acceptable and don't shock me.
Now private
should be favored as much as possible as it prevents undesirable coupling while package-private
that creates a little more coupling should be used with relevancy.
In most of cases our code is not used by any other services/APIs and we actually don't care of 'private' benefits.
Even as you develop a library to be used by some clients, using the package modifier is not bad as the classes in the package-private
doesn't make part directly of the API.
But what I believe we do care is to create readable simple unit tests. Considering this, why do not create all methods in class as 'package-private' by default and make them 'private' only in case when we really need this?
Reversely, unit testing and private
modifiers are not incompatible at all.
I agree that using package-private
modifier instead of private
allows to test/mock/switch easily members of classes.
In some cases, this practice is acceptable.
Now generalizing this is before all a design choice.
Personally I use the package-private
modifier only as really relevant (a real issue for testing or a internal processing to share among other classes of the same package) because beyond making unit testing easier (which is a good point), I think that this kind of practice may favor a design that couples the classes more strongly than required.
For example, suppose in a B
class you may access a field/method of a A
class instance because these are in the same package.
Suppose that conceptually this field make part of a very internal part of the A
implementation and that it have not be known by other classes to allows to change it later.
But as this field/method is package-private, now nothing prevents you from making it as you can.
I don't like that.
To finish, I would say that you should not worry about unit testing of private
methods.
Internals don't make part of the API. You don't need to test it.
Now if the private method is invoked multiple times or you really need to test this processing, nothing prevents you from extracting it in another class to make it testable and to have a way to mock the processing if required (to avoid test it multiple times).

- 125,838
- 23
- 214
- 215
-
Access to methods could be closed by good package separation. I believe almost all teams nowadays have code review practice. So in most cases I believe coupling is not an issue for package-private. If somebody could create in same package class/method it means he could change private to public access as well. This is only could be found by code review. Today even IDE will suggest to you to change method modifier to private if it's not used outside class. This means that you will have to test your methods using accessible methods what IMHO will increase test complexity and reduce readability. – Aliaksei Yatsau Dec 02 '17 at 16:19
-
davidxxx, Sorry, forgot to say Thank you for your thoughts. I'm trying to say that nowadays big percentage of developers doesn't think about method access at all. IDE says it could be 'private' and they blindly mark it as 'private'. This 'private' method could be really big, could have really big asymptotic complexity and it won't be 100% covered only because of access level. That's why I've made assumption, maybe by default if this method is not used outside class it should have 'package-private' access level. We still will have proper security and possibility to create good tests. – Aliaksei Yatsau May 02 '18 at 03:12
-
"I'm trying to say that nowadays big percentage of developers doesn't think about method access at all." From my own experience, unfortunately a big percentage of developers doesn't care a lot of the code quality. Maybe that your idea comes the fact that you have to cope with not rigorous enough developers. It is a workaround that i can understand but in the absolute i don't agree. – davidxxx May 04 '18 at 12:44