Change method accessibility in order to test it - java

I have a public method that calls group of private methods.
I would like to test each of the private method with unit test as it is too complicated to test everything through the public method ,
Is think it will be a bad practice to change method accessibility only for testing purposes.
But I dont see any other way to test it (maybe reflection , but it is ugly)

Private methods should only exist as a consequence of refactoring a public method, that you've developed using TDD.
If you create a class with public methods and plan to add private methods to it, then your architecture will fail.
I know it's harsh, but what you're asking for is really, really bad software design.
I suggest you buy Uncle Bob's book "Clean Code"
http://www.amazon.co.uk/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882
Which basically gives you a great foundation for getting it right and saving you a lot of grief in your future as a developer.

There is IMO only one correct answer to this question; If the the class is too complex it means it's doing too much and has too many responsibilities. You need to extract those responsibilities into other classes that can be tested separately.
So the answer to your question is NO!
What you have is a code smell. You're seeing the symptoms of a problem, but you're not curing it. What you need to do is to use refactoring techniques like extract class or extract subclass. Try to see if you can extract one of those private methods (or parts of it) into a class of itself. Then you can add unit test to that new class. Divide and conquer untill you have the code under control.

You could, as has been mentioned, change the visibility from private to package, and then ensure that the unit-tests are in the same package (which should normally be the case anyway).
This can be an acceptable solution to your testing problem, given that the interfaces of the (now) private functions are sufficiently stable and that you also do some integration testing (that is, checking that the public methods call the private ones in the correct way).
There are, however, some other options you might want to consider:
If the private functions are interface-stable but sufficiently complex, you might consider creating separate classes for them - it is likely that some of them might benefit from being split into several smaller functions themselves.
If testing the private functions via the public interface is inconvenient (maybe because of the need for a complex setup), this can sometimes be solved by the use of helper functions that simplify the setup and allow different tests to share common setup code.

You are right, changing the visibility of methods just so you are able to test them is a bad thing to do. Here are the options you have:
Test it through existing public methods. You really shouldn't test methods but behavior, which normally needs multiple methods anyway. So stop thinking about testing that method, but figure out the behavior that is not tested. If your class is well designed it should be easily testable.
Move the method into a new class. This is probably the best solution to your problem from a design perspective. If your code is so complex that you can't reach all the paths in that private method, parts of it should probably live in their own class. In that class they will have at least package scope and can easily be tested. Again: you should still test behavior not methods.
Use reflection. You can access private fields and methods using reflection. While this is technical possible it just adds more legacy code to the existing legacy code in order to hide the legacy code. In the general case a rather stupid thing to do. There are exceptions to this. For example is for some reason you are not allowed to make even the smallest change to the production source code. If you really need this, google it.
Just change the visibility Yes it is bad practice. But sometimes the alternatives are: Make large changes without tests or don't test it at all. So sometimes it is ok to just bite the bullet and change the visibility. Especially when it is the first step for writing some tests and then extracting the behavior in its own class.

Related

Unit Test Practice About Field Accessibility

I have a tree data structure for example
public class Tree {
class Node {
//stuffs...
}
private Node root;
// ...
}
I'm using junit4. In my unit test, I'd like to run some sanity check where I need to traverse the tree (e.g. check the binary search tree properties are preserved). But since the root is kept private, I can't traverse it outside the class.
Something I can think about are:
A getter for root can prevent the reference itself from being changed, but external code still may change fields in root.
A test is not a part of the data structure itself, I don't really want to put it in the Tree class. And even I do, I have to delete them after the test is done.
Please tell me the right thing to do, thanks.
There's multiple things you can do, a few options are:
Make a public getter (but this breaks code encapsulation, only should be considered if you for some odd reason cannot put tests in the same package)
Write a package-private getter and place the tests in the same package (probably the best solution)
Use reflection to gain access to the value (not recommended)
I would personally go with option 2 (please see my last paragraph for my recommend answer, since I would not do any of the above). This is what we used in industry to test things that we can't normally access to. It is minimally invasive, it doesn't break encapsulation like a public getter does, and it doesn't require you to do intrusive reflection code.
As a discussion on why we didn't use (3), I was on a project once where the lead developer decided to do exactly this in all his unit tests. There were tens of thousands of unit tests which were all using reflection to verify things. The performance gain we got from converting them away from a reflection-assisting library was nice enough that we got a lot more snappy feedback when we ran our unit tests.
Further, you should ask yourself if you need to do such tests. While testing is nice, you should ideally be unit testing the interface of your stuff, not reaching into the guts to assert everything works. This will make it very painful if you ever need to refactor your class because you'll invalidate a bunch of tests when you touch anything. Therefore I recommend only testing the public methods and be very rigorous in your tests.

Testing static methods of 3rd party Java SDKs

I've been working with Java, specifically in Android, for a few months now and I've found that working with PowerMockito is something I'd rather not do. The complexities of keeping it working have outweighed any benefit of it. I also think I'd agree with most of the comments I've read on Stackoverflow that say not to use PowerMockito, so please keep that in mind when answering my question. I am looking for guidance to testing without PowerMockito.
My question is, when writing code that interfaces with a 3rd party SDK that has some static method, how would you test it? Specifically, when it seems the only thing really worth testing is a behaviour? ie that the static method was called?
I can and do put these 3rd party services behind adapter classes usually. And I can test that my adapter was called. But how do you live with not ever being able to test that the 3rd party itself was called and maybe confirm which arguments it was called with? Is this the only thing available in my toolbox? to limit logic as much as possible so that the untested area is less likely to fail?
When explaining this to someone coming from a dynamically typed language would you just say that the test wasn't valuable? I'm thinking at this point that these kind of tests are low value, but I can understand why others would want to test this kind of thing. Its the kind of test I've seen written a lot in Ruby projects I've worked on.
The one thing I have done in the past in similar situations:
created a tiny wrapper interface and an impl class calling that static method; and test verifying that the wrapper is called
a single test case that invokes that impl class and thereby the real static method.
If one is "lucky" that call has an observable effect, for example some exception gets thrown (that is the problem with a lot of static code in my context - it simply breaks unless the whole stack is running). And then you check for that. But I also agree: there isn't much value in doing so. It proofs correct plumbing, at the cost of being subject to change whenever the behavior of that static method changes.

Is private necessary for a standalone Java app? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I have read through a bunch of best practices online for JUnit and Java in general, and a big one that people like to point out is that fields and methods should be private unless you really need to let users access them. Class variables should be private with getters and setters, and the only methods you should expose should be ones that users will call directly.
My question: how strictly necessary are these rules when you have things like standalone apps that don't have any users? I'm currently working on something that will get run on a server maybe once a month. There are config files that the app uses that can be modified, but otherwise there is no real user interaction once it runs. I have mostly been following best practices but have run into issues with unit testing. A lot of the time it feels like I am just jumping through hoops with my unit testing getting things just right, and it would be much easier if the method or whatever was public or even protected instead.
I understand that encapsulation will make it easier to make changes behind the scenes without needing to change code all over, but without users to impact that seems a bit more flimsy. I am just making my current job harder on the off-chance it will save me time later. I've also seen all of the answers on this site saying that if you need to unit test a private method you are doing something wrong. But that is predicated on the idea that those methods should always be private, which is what I am questioning.
If I know that no one will be using the application (calling its methods from a jar or API or whatever) is there anything wrong with making everything protected? Or even public? What about keeping private fields but making every method public? Where is the balance between "correct" accessibility on pieces of code, and ease of use?
It is not "necessary", but applying standards of good design and coding principles even in the "small" projects will help you in the long run.
Yes, it takes discipline to write good software. Languages are tools that help you accomplish a goal. Like any tool, they can be misused, and when misused can be dangerous. Power tools, like a table saw, can be very dangerous if misused, so if you care about your own safety you always follow proper procedure, even if it might feel a little inconvenient (or you end up nicknamed "stubby").
I'd argue that it's on the small projects, where you want to cut corners and "just write the code", that adhering to the best practices is most important. You are training yourself in the proper use of your tools, so when it really matters you do the right thing automatically.
Also consider that projects that start out "small" can evolve over time to become quite large as you keep adding enhancements and new functionality. This is the nature of agile software development. If you followed best practices from the start you'll find it much easier to adapt as the project grows.
Another factor is that using OOP principles is a way of taming complexity. If you have a well-defined API and, for example, use only getters and setters, you can partition off the API from the implementation in your own mind. After writing class A, when writing a client of A, say B, you can think only about the API. Later when you need to enhance A you can easily tell what parts of A affect the API vs what parts are purely internal. If you didn't use encapsulation you'd have to scan your entire codebase to see if a change to A would break something else.
Do I apply this to EVERYTHING I write? No, of course not. I don't do this with short single-use scripts in dynamic languages (Perl, AWK, etc) but when writing Java I make it a point to always write "good" code, if only to keep my skills sharp.
There is generally no necessity to follow any rules as long as your code compiles and runs correctly.
However code style "best practices" have proven to enhance code quality, especially over time when a project develops/matures. Making fields private makes your code more resilient to later changes; if you ommit the getters/setters and access fields directly, any changes to a field impact related code much more directly.
While there is seemingly no advantange in a getter/setter at first, the advantage lies in the future: A getter forces any code working with the attribute through a single point of control which in case of any changes related to that field helps either mask the concrete representation/location of the field and/or allows for polymorphism when required whithout changes/checking all the existing callers.
Finally the less surface (accessible methods/fields) a class exposes to other classes (users) the less you have to maintain. Reducing the exposed API to the absolute minimum reduces coupling between classes, which again is an advantage when something needs to be changed. Striving to hide the inner workings of every object as good as possible is not a goal by itself, its the advantages that result from it that are the goal.
As always, good balancing is always required. But when in doubt, it is better to error/lean on the side of "source code quality" practices; instead of taking too many shortcuts; as there are many different aspects in your "simple" question one should consider:
It is hard to anticipate what will happen to some piece of software over time. Yes, you don't have any users today. But you know what: one major property of great tools is ... as soon as other people see them, they want to use them, too. And all of a sudden, you have users. And feature requests, bug reports, ... and make no mistake: first people will love you for the productivity gain from your tool; and then they will start to put pressure on you because all of a sudden your tool is essential for other people to make their goals.
Many things are fine to be addressed via convention. Example: sometimes, if I would only be using public methods of my "class under test", unit tests become more complicated than necessary. In such a case, I absolutely have no problem about putting a getter here or there that allows me to inspect the internal state of my "class under test"; so that my test can trigger some activity; and then call the getter. I make those methods "package protected"; and I put a // used for unit testing above them. I have not seen problems coming out of that informal practice. Please note: those methods should only be used in test cases. No other production class is supposed to call them.
Regarding the core of your question on private stuff: I think, one should always hide implementation details from the outside. Whenever you write a piece of code that is supposed to live longer than the next hour, you should do the right thing - and try to write code with very high quality. And making the internals of your objects visible on the outside
comes only with drawbacks; there is nothing positive in doing so.
Good OO is about using models that come with certain behavior.
Internal state should stay internal; there is no benefit in
exposing. For the record: sometimes, you have simple data
containers. Classes that only have some fields, but no methods on
them. In that case, yeah, make the fields public; there is (not
much) advantage in providing getters/setters. ( See "Clean Code" by
Robert Martin, chapter 6 on "Objects and Data structures")

Sanity Check - Significant increase in the number of objects when using JUNIT

I am using Junit for the first time in a project and I'm fascinated by the way it is forcing me to restructure my code. One thing I've noticed is that the number of objects I've created in order to be able to test chunks of code is significantly increasing. Is this typical?
Thanks,
Elliott
Yes, this is normal.
In general the smaller/more focused your classes and methods are, the easier to understand and test them. This might produce more files and actual lines of code, but it is because you are adding more abstractions that makes your code have a better/cleaner design.
You may want to read about the Single Responsibility Principle. Uncle Bob also has some re-factoring examples in his book called Clean Code where he touches on exactly these points.
One more thing when you are unit testing. Dependency Injection is one of the single most important thing that will save you a lot of headaches when it comes to structuring your code. (And just for clarification, DI will not necessary cause you to have more classes, but it will help decouple your classes more from each other.)
Yes, I think this is fairly typical. When I start introducing testing code into a legacy codebase, I find myself creating smaller utility classes and pojos and testing those. The original class just becomes a wrapper to call these smaller classes.
One example would be when you have a method which does a calculation, updates an object and then saves to a database.
public void calculateAndUpdate(Thing t) {
calculate(t); // quite a complex calculation with mutliple results & updates t
dao.save(t);
}
You could create a calculation object which is returned by the calculate method. The method then updates the Thing object and saves it.
public void calculateAndUpdate(Thing t) {
Calculation calculation = new Calculator().calculate(t); // does not update t at all
update(t, calculation); // updates t with the result of calculation
dao.save(t); // saves t to the database
}
So I've introduced two new objects, a Calculator & Calculation. This allows me to test the result of the calculation without having to have a database available. I can also unit test the update method as well. It's also more functional, which I like :-)
If I continued to test with the original method, then I would have to unit test the calculation udpate and save as one item. Which isn't nice.
For me, the second is a better code design, better separation of concerns, smaller classes, more easily tested. But the number of small classes goes up. But the overall complexity goes down.
depends on what kind of objects you are referring to. Typically, you should be fine with using a mocking framework like EasyMock or Mockito in which case the number of additional classes required solely for testing purposes should be pretty less. If you are referring to additional objects in your main source code, may be unit testing is helping you refactor your code to make it more readable and reusable, which is a good idea anyways IMHO :-)

Java getter/setter style question

I have a question about Java style. I've been programming Java for years, but primarily for my own purposes, where I didn't have to worry much about style, but I've just not got a job where I have to use it professionally. I'm asking because I'm about to have people really go over my code for the first time and I want to look like I know what I'm doing. Heh.
I'm developing a library that other people will make use of at my work. The way that other code will use my library is essentially to instantiate the main class and maybe call a method or two in that. They won't have to make use of any of my data structures, or any of the classes I use in the background to get things done. I will probably be the primary person who maintains this library, but other people are going to probably look at the code every once in a while.
So when I wrote this library, I just used the default no modifier access level for most of my fields, and even went so far as to have other classes occasionally read and possibly write from/to those fields directly. Since this is within my package this seemed like an OK way to do things, given that those fields aren't going to be visible from outside of the package, and it seemed to be unnecessary to make things private and provide getters and setters. No one but me is going to be writing code inside my package, this is closed source, etc.
My question is: is this going to look like bad style to other Java programmers? Should I provide getters and setters even when I know exactly what will be getting and setting my fields and I'm not worried about someone else writing something that will break my code?
Even within your closed-source package, encapsulation is a good idea.
Imagine that a bunch of classes within your package are accessing a particular property, and you realize that you need to, say, cache that property, or log all access to it, or switch from an actual stored value to a value you generate on-the-fly. You'd have to change a lot of classes that really shouldn't have to change. You're exposing the internal workings of a class to other classes that shouldn't need to know about those inner workings.
I would adhere to a common style (and in this case provide setters/getters). Why ?
it's good practise for when you work with other people or provide libraries for 3rd parties
a lot of Java frameworks assume getter/setter conventions and are tooled to look for these/expose them/interrogate them. If you don't do this, then your Java objects are closed off from these frameworks and libraries.
if you use setters/getters, you can easily refactor what's behind them. Just using the fields directly limits your ability to do this.
It's really tempting to adopt a 'just for me' approach, but a lot of conventions are there since stuff leverages off them, and/or are good practise for a reason. I would try and follow these as much as possible.
I don't think a good language should have ANY level of access except private--I'm not sure I see the benefit.
On the other hand, also be careful about getters and setters at all--they have a lot of pitfalls:
They tend to encourage bad OO design (You generally want to ask your object to do something for you, not act on it's attributes)
This bad OO design causes code related to your object to be spread around different objects and often leads to duplication.
setters make your object mutable (something that is always nice to avoid if you can)
setters and getters expose your internal structures (if you have a getter for an int, it's difficult to later change that to a double--you have to touch every place it was accessed and make sure it can handle a double without overflowing/causing an error, if you had just asked your object to manipulate the value in the first place, the only changes would be internal to your object.
Most Java developers will prefer to see getters and setters.
No one may be developing code in your package, but others are consuming it. By exposing an explicitly public interface, you can guarantee that external consumers use your interface as you expect.
If you expose a class' internal implementation publicly:
It isn't possible to prevent consumers from using the class inappropriately
There is lost control over entry/exit points; any public field may be mutated at any time
Increase coupling between the internal implementation and the external consumers
Maintaining getters and setters may take a little more time, but offers a lot more safety plus:
You can refactor your code any time, as drastically as you want, so long as you don't break your public API (getters, setters, and public methods)
Unit testing well-encapsulated classes is easier - you test the public interface and that's it (just your inputs/outputs to the "black box")
Inheritance, composition, and interface designs are all going to make more sense and be easier to design with decoupled classes
Decide you need to add some validation to a mutator before it's set? One good place is within a setter.
It's up to you to decide if the benefits are worth the added time.
I wouldn't care much about the style per se (or any kind of dogma for that matter), but rather the convenience in maintainability that comes with a set of getter/setter methods. If you (or someone else) later needed to change the behavior associated with a change of one of those attributes (log the changes, make it thread-safe, sanitize input, etc.), but have already directly modified them in lots of other places in your code, you will have wished you used getter and setter methods instead.
I would be very loath to go into a code review with anything but private fields, with the possible exception of a protected field for the benefit of a subclass. It won't make you look good.
Sure, I think from the vantage point of a Java expert, you can justify the deviation from style, but since this is your first professional job using Java, you aren't really in that position.
So to answer your question directly: "Is this going to look like bad style?" Yes, it will.
Was your decision reasonable? Only if you are really confident that this code won't go anywhere. In a typical shop, there may be chances to reuse code, factor things out into utility classes, etc. This code won't be a candidate without significant changes. Some of those changes can be automated with IDEs, and are basically low risk, but if your library is at the point where it is stable, tested and used in production, encapsulating that later will be regarded as a bigger risk than was needed.
Since you're the only one writing code in your closed-source package/library, I don't think you should worry too much about style - just do what works best for you.
However, for me, I try to avoid directly accessing fields because it can make the code more difficult to maintain and read - even if I'm the sole maintainer.
Style is a matter of convention. There is no right answer as long as it is consistent.
I'm not a fan of camel, but in the Java world, camelStyle rules supreme and all member variables should be private.
getData();
setData(int i);
Follow the Official Java code convention by Sun (cough Oracle) and you should be fine.
http://java.sun.com/docs/codeconv/
To be brief, you said "I'm asking because I'm about to have people really go over my code for the first time and I want to look like I know what I'm doing". So, change your code, because it does make it look like you do not know what you are doing.
The fact that you have raised it shows that you are aware that it will probably look bad (this is a good thing), and it does. As has been mentioned, you are breaking fundamentals of OO design for expediency. This simply results in fragile, and typically unmaintainable code.
Even though it's painful, coding up properties with getters and setters is a big win if you're ever going to use your objects in a context like JSP (the Expression Language in particular), OGNL, or another template language. If your objects follow the good old Bean conventions, then a whole lot of things will "just work" later on.
I find getters and setters are better way to program and its not about only a matter of coding convention. No one knows the future, so we can write a simple string phonenumber today but tomorrow we might have to put "-" between the area code and the number, in that case, if we have a getPhonenumber() method defined, we can do such beautifications very easily.
So I would imagine, we always should follow this style of coding for better extensibility.
Breaking encapsulation is a bad idea. All fields should be private. Otherwise the class can not itself ensure that its own invariants are kept, because some other class may accidentally modify the fields in a wrong way.
Having getters and setters for all fields is also a bad idea. A field with getter and setter is almost the same as a public field - it exposes the implementation details of the class and increases coupling. Code using those getters and setters easily violates OO principles and the code becomes procedural.
The code should be written so that it follows Tell Don't Ask. You can practice it for example by doing an Object Calisthenics exercise.
Sometimes I use public final properties w/o get/setter for short-living objects which just carry some data (and will never do anything else by design).
Once on that, I'd really love if Java had implied getters and setters created using a property keyword...
Using encapsulation is a good idea even for closed source as JacobM already pointed out. But if your code is acting as library for other application, you can not stop the other application from accessing the classes that are defined for internal use. In other words, you can not(?) enforce restriction that a public class X can be used only by classes in my application.
This is where I like Eclipse plugin architecture where you can say what packages in my plugin can dependent plugins access during runtime. JSR 277 aimed at bringing this kind of modular features to JDK but it is dead now. Read more about it here,
http://neilbartlett.name/blog/2008/12/08/hope-fear-and-project-jigsaw/
Now the only option seems to be OSGi.
While I am well aware about the common pressure to use getters and setters everywhere regardless the case, and the code review process leaves me no choice, I am still not convinced in the universal usefulness of this idea.
The reason, for the data carrying classes, over ten years of development it has never been for me a single case where I would write anything different from set the variable in the setter and read the variable in the getter while lots of time has been spent on generating, understanding and maintaining this cargo cult code that seems not making any sense.
The data class is a structure or record, not a class. It does not do anything itself. Other classes are making changes to it. It should not be any functionality there at all, leave alone the functionality in the setters or getters. Java probably needs a separate keyword for the multi-field data record that has no methods.
From the other side, the process seems gone so far now that probably makes a lot of sense to put getters and setters just from beginning, even first time in the new team. It is important not to conflict with the team.

Categories