3 ms·
If your class is doing so many things that you can't reasonably test everything but through the private methods, how about extracting a helper for those things
by sverhagen 3y ago
If your class is doing so many things that you can't reasonably test everything but through the private methods, how about extracting a helper for those things which has testable public (or package private, if you have to) methods!? Did I just sneakily bypass the rules, or make the code better overall? I don't know anymore...
- BugsJustFindMe 3y ago> If your class is doing so many things that you can't reasonably test everything but through the private methods, how about extracting a helper for those things which has testable public When your solution to not wanting to write tests for important behavior is to trick yourself into wanting to by adding extra layers of code for no other reason, maybe the rule stopping you from doing it was wrong.
- sverhagen 3y agoI acknowledged right away that it was a hack. And if it wasn't clear, by that I meant that the private method rule shouldn't be hard. It's can still be a smell, though, but I'm trying to be pragmatic.
- boxed 3y agoIt's not about that imo. It's about having tests that are limited in scope as much as possible, so if they fail it's much easier to understand the problem. Ideally tests should be run in a specific order, from most low level to most high level. So tiny basic functions first, then functions that use those functions, then functions that use THOSE functions, etc until you have end-to-end tests. Unfortunately I know of no testing system that has such a hierarchy.
- The_Colonel 3y agoBasically every decent test framework has a concept of test suites which can be used for this purpose.
- boxed 3y agoCould you name one concretely and show how a suite will do this?
- JohnBooty 3y agoI agree that if your private functionality has grown complex, that's a strong "code smell" that perhaps it needs to be extracted. But yeah, then you've changed it from private to public.
- stouset 3y agoIn my experience refactoring and making things public is an entirely reasonable thing to do! I often find that when I have a very complicated structure with lots of behavior, there’s some other cohesive unit of functionality living inside. That part is often private, but extracting it into a separate structure with public interfaces makes complete sense. From the perspective of consumers of the original class, all of this is still implementation detail that can’t be directly accessed. But there’s nothing wrong about accessing that underlying bit directly through its own public interface.
- sverhagen 3y agoPrivate methods can benefit from knowledge about the class they live in, and be only good enough for their purpose in that class. When elevated to public methods, you may want them to be more defensive than when they were private, which is an investment that doesn't pay off in itself. People may also be tempted to reuse your public methods now, even if they were never intended for that. Java has package-private for that (I guess). I'm not a fan of package-private, but then again, I'm writing small micro-services and considering the code inside this service "friendly" to my class, i.e. not abusing public methods without looking inside them to see if they're up for the job.
- stouset 3y agoThat's not really what I'm talking about at all. Private methods are often useful for handling internal details. But often when you have a lot of private methods, you're bundling too much functionality into one object. I have found that it is very common that I get significant improvements in readability, testability, and comprehensibility when I decompose a large structure with a lot of private methods into a few smaller structures that operate on each others' public API.