Avoid accessing private properties directly from the same class - java

This is a very simple example where accessing directly could be dangerous
class Something{
public static final int MAX=123;
private int prop;
final void riskyMethod()
{
this.prop=800; //this is wrong
}
final void safeSetProp(int x)
{
if(x<MAX)
{
prop=x;
}
}
}
I know it could be done encapsulating "prop" in another class,
and defining it there as private, but that's a lot of useless code overhead!
Is there a way to force the use of methods to access same class properties?
a keyword? any trick?
I confess I have done things like this to avoid accidental access by the same class
private int IKWIDprop; //IKWID = I Know What I am Doing
I am sure you could know a better approach =)
Regards!

This is your class, come on! You always know what you are doing. If you don't, write tests. I understand you want to force the usage of getter instead of raw field in case at some point in the future the getter will be equipped with some extra logic. But because this is your class, you are fully responsible and capable of maintaining this code.
Bizzare Hungarian notation only clutters the code. Unit test your class to make sure nobody damages your work (including yourself). Nobody reads documentation and Javadocs, not to mention nobody will understand TIASCWIAFDPUGIage (thisIsASpecialCaseWhenIAccessFieldDirectlyPleaseUseGetterInstead_Age), including you after a while.
BTW if you force the usage of encapsulating getter inside your class, how does the getter itself access the field? So go back to earth and be reasonable. Having a strong suite of unit tests is much more helpful, reliable and provides better documentation.
UPDATE: Actually, there is a (sort of) clean way. You can use AspectJ, with few clever pointcuts, will catch raw private field access excluding some special cases. It can be executed at compile time to fail the build or at runtime. The pointcut would say something like: "each private field access from a method that is not annotated with #ThisIsASetter should generate compile time error. Maybe somebody more fluent with AspectJ can write this?

no, there is no such keyword. I advice you to write good documentaton, comments and to promis to beat those, who will use direct assigning of the value

One "trick" that comes to mind is to put any fields like this into an abstract class which provides the necessary getter/setter methods. Then, derive your "real" class from the abstract class, and now any writing to those private fields need to be done via the "safe" setter methods.
Of course, this is a ton of extra overhead, and it still doesn't prevent you from writing incorrect values in the abstract parent class anyway.
The point of private is to ensure that internal class invariants aren't disturbed incorrectly by code that consumes the class. As you note, it does not prevent the class itself from messing with them, because presumably the class knows what it's doing! If you want to ensure that certain invariants are correct prior to relying on them, you can always use assert statements. If they fire, you can look through your code and see what you've done that's caused the problem.
In general, your best bet is to just be careful with your code, rather than trying any "tricks".

Related

Java Class That Has 90% Static Members. Good Practice Or What?

I'm 14 and have been learning java for about 4/5 months. I'm coding a game now called super mario winshine and i wanted to know if it is good practice to have a class that is mostly static variables.
The class is the one that holds all the information for the game's level/world. Since I only need one version of this class, and lots of other classes will be using it, I choose to make all the variables static. Is this good practice?
I have considered the fact that i could keep the variables "non-static" and just clone the main object i use for that class, but I thought i would rather sacrifice "O-O" for memory in this case.
As soon as you want to have two or more worlds this will fail. Say, when your first release is a runaway success and you want to add the "parallel universe" expansion set.
In my experience, 90% of the time when marketing says "oh, don't worry, there will only be one Application/Window/Database/User" they are wrong.
ADDED
I would also avoid using a true Singleton pattern with World.getInstance() etc. Those are for the rare cases where it really is an essential requirement that there only be one of something. In your case, you are using it as a convenience, not a requirement.
There is no perfect fix, YMMV, but I'd consider a single static method, something like
World World.getWorld(String name)
and then you call real (non-static) methods on the World that is returned. For V1 of your program, allow null to mean "the default world".
Some might put that method into a class named WorldManager, or, perhaps showing my age, a more clever name like Amber. :-)
It all depends upon what your methods and classes are. There is no problem in defining utility methods as static methods in a class. There is no need to make it a singleton as others are suggesting. Look at the Math class from java.lang package. It has lot of utility methods but it isn't a singleton.
Also check out static imports functionality. Using this you doesn't need to qualify method calls with the class name.
Well, what you are doing is definitely an option. Or you could use a singleton pattern:
public class World {
private static World instance = new World();
private World() {
}
public static World getInstance() {
return instance;
}
}
Now just use World.getInstance() everywhere to have a unique object of this type per application.
I would say it's definitely not a good practice.
I've not seen your code, but having several static variables in a class that other classes access freely seems to indicate that you're not really using object orientation/classes but more just writing procedural code in Java. Classes should generally encapsulate/hide all their variables - static or not - from access from other classes so that other classes don't depend on how the class is implemented.
The static part also causes problems with making threads work (global variables are hard to lock in a good way so that nothing deadlocks) and with unit testing (mocking is all but impossible)
I also agree with the other posters, if you need "global variables", at least make them singletons. That allows you to change strategy easier later and does not lock you to one world.
Edit: I'm definitely not advocating singletons as a good pattern here if someone read it like that, but it does solve some problems with static variables, esp. regarding testing/mocking compared to just statics so I'd say it's a ever so slightly lighter shade of gray :) It is also a pattern that is easier to gradually replace with better patterns by for example using a IoC container.
I think it is fine as long as you don't need anything more sophisticated, in other words, static fields are OK as long as different objects (including subclasses if there will be any) do not need different values.
You code by yourself, refactoring is easy with modern tools, me says don't fix it until it is broken, and focus on the algorithmic aspects of your project.
Perhaps you may think to encapsulate all those static fields within a different static class, as it is a good principle to "keep what changes seperate from what does not". Chances are one day you will want to initiate that static class with different values, for example want to read the initial values from an XML file and/or registry, add behaviour, etc. so instead of a static class you will implement it with a Singleton pattern.
But clearly that is not the concern of today. Till then, enjoy!
You may wish to look into implementing this class as a singleton, while there is nothing particularly wrong with your approach it may lead to some inflexibility further down the road.
Also you should take in to consideration the purpose of static members which is to be a member of the class and 'act' on/with the class not an instance of it. For example the static method in a singleton returns either a new instance of the class if one doesn't already exist or returns the instance, and because the method is static you do not instantiate a new one. This is probably worth a read because it can be somewhat confusing when determining the appropriate use of static members
I'm not sure what you are really talking about from your short description, so I'll try this:
public class Level {
static List<Mushroom> mushrooms;
static List<Coin> coins;
...
}
Is that you were describing?
You asked if this is "good practice" and I can tell you that this looks very odd, so, no, it's not.
You gain absolutely nothing by doing this. You make it impossible to have more than one Level, which brings no advantage, but it could cause trouble in the future.
I didn't understand your last paragraph where you say you made most things static to save memory. You would usually create one Level and it would be passed around (without cloning) to the various classes/methods that read from it or modify it.

Single instance with methods in java

I am wondering about programming decision - which I think is matter of style.
I need to have single instance of class which has only methods and no attributes.
To obtain that in java I have two options:
create an abstract class with static methods within, thus it will not be possible to create any instance of the class and that is fine,
use a singleton pattern with public methods.
I tend to go for second approach although met with 1. Which and why is better of those, or there is third option.
Would it make sense for that singleton to implement an interface, allowing you to mock out those methods for test purposes?
I know it goes against testing dogma these days, but in certain situations I think a static method is fine. If it's the kind of behaviour which you're never going to want to fake for test purposes, and which is never going to be polymorphic with other implementations, I don't see much point in making a singleton. (Singletons are also generally the enemy of testability, although if you only directly refer to them in the injection part of your code, they can implement appropriate interfaces so their singletoneity never becomes a problem.)
It's worth mentioning that C# has "static classes" for this kind of situation - not only do they prohibit other code from deriving from or instantiating the class, but you can't even use it as a parameter. Basically it signals the intent very clearly.
I would definitely suggest at least having a private constructor to prevent instantiation by the outside world.
My personal view is that the class should contain a private constructor and NOT be abstract. Abstract suggest to a reader that there is a concrete version of the class somewhere, and they may waste time searching for it. I would also make sure you comment your code effectively.
public class myClass {
/** This class should never be instantiated. */
private myClass() {
}
public static void myMethod() {
}
...
//etc
...
}
For option #1, it may not even be that important to restrict instantiation of your static utility class. Since all it has is static methods and no state, there is no point - but neither harm - instantiating it. Similarly, static methods can't be overridden so it does not make sense - nor difference - if it is subclassed.
If it had any state, though - or if there is a chance that it will get stateful one day - it may be better to implement it as a normal class. Still I would prefer not to use it as a Singleton, rather to pass its sole instance around via dependency injection. This makes unit testing so much easier in the long run.
If it holds a state I would use the singleton pattern with private constructors so you can only instantiate from within the class. If it does not hold a state, like the apache commons utility classes, I would use the static methods.
I've never seen the problem with static methods. You can think of static methods as somehow breaking OO, but they make perfect sense if you think of static as a marker that something is stateless. You find this in the java apis in places like java.Math. If you're worried about subclassing you can always make it final.
There is a danger in that a class like that can end up as a "utility method garbage can", but as long as the functionality doesn't diverge too much then there's nothing wrong with it.
It's also clearer, as there's no need to manage an object lifecycle like you would with a singleton (and since there's no state, what's the point of that anyway?).
For a single instance, I suggest you have an enum, with one instance.
However, for a class with no attributes, you don't have to have an instance. You can use a utility class. You can use an enum, with no instances and only static methods. Note: this cannot be easily mocked out.
You can still implement an interface if you ever need to mock out the implementation in testing.

the use of private keyword

I am new to programming. I am learning Java now, there is something I am not really sure, that the use of private. Why programmer set the variable as private then write , getter and setter to access it. Why not put everything in public since we use it anyway.
public class BadOO {
public int size;
public int weight;
...
}
public class ExploitBadOO {
public static void main (String [] args) {
BadOO b = new BadOO();
b.size = -5; // Legal but bad!!
}
}
I found some code like this, and i saw the comment legal but bad. I don't understand why, please explain me.
The most important reason is to hide the internal implementation details of your class. If you prevent programmers from relying on those details, you can safely modify the implementation without worrying that you will break existing code that uses the class.
So by declaring the field private you prevent a user from accessing the variable directly. By providing gettters and setters you control exactly how a user may control the variable.
The main reason to not just make the variable public in the first place is that if you did make it public, you would create more headaches later on.
For example, one programmer writes public getters and setters around a private member variable. Three months later, he needs to verify that the variable is never "set" to null. He adds in a check in the "setFoo(...)" method, and all attempts to set the variable will then be checked for "setting it to null". Case closed, and with little effort.
Another programmer realizes that putting in public getters and setters around a private member variable is violating the spirit of encapsulation, he sees the futility of the methods and decides to just make the member variable public. Perhaps this gains a bit of a performance boost, or perhaps the programmer just wants to "write it as it is used". Three months later, he needs to verify that the variable is never "set" to null. He scans every access to the variable, effectively searching through the entire code base, including all code that might be accessing the variable via reflection. This includes all 3rd party libraries which has extended his code, and all newly written modules which used his code after it was written. He then either modifies all calls to guarantee that the variable is never set to null. The case is never closed, because he can't effectively find all accesses to the exposed member, nor does he have access to all 3rd party source code. With imperfect knowledge of newly written modules, the survey is guaranteed to be incomplete. Finally he has no control over the future code which may access the public member, and that code may contain lines which set the member variable to null.
Of course the second programmer could then break all existing code by putting "get" and "set" methods around the variable and making it private, but hey, he could have done that three months earlier and saved himself the explanation of why he needed to break everyone else's code.
Call it what you will, but putting public "get" and "set" methods around a private member variable is defensive programming which has been brought about by many years (i.e. decades) of experience.
Anything public in your class is a contract with the users of the class. As you modify the class, you must maintain the contract. You can add to the contract (new methods, variables, etc.), but you can't remove from it. Idealy you want that contract to be as small as possible. It is useful to make everything private that you can. If you need direct access from package members, make it protected. Only make those things public which are required by your users.
Exposing variables means that you are contracting forever, to have that variable and allow users to modify it. As discussed above, you may find you need to invoke behaviour when a variable is accessed. This can be be done if you only contract for the getter and setter methods.
Many of the early Java classes have contracts which require them to be thread safe. This adds significant overhead in cases where only one thread can access the instance. Newer releases have new classes which duplicate or enhance the functionality but drop the syncronization. Hence StringBuilder was added and in most cases should be used instead of StringBuffer.
Its considered bad mainly because you loose control over who can change the value and what happens when the value changes.
In tiny application written by you for you it won't seem that important but as you start developing for larger and larger applications having control over who changes what and when becomes critical.
Imagine from your example above, you publish library as is, other people use it, then you decide you wanted to calculate another value in your bad class when the size changes ... suddenly the bad00 class has no way of knowing and you can't change it because other people rely on it.
Instead if you had a set method you could extend it to say
void SetSize(int newSize)
{
size = newSize;
DoCalculation;
}
You can extend the functionality without breaking other peoples reliance on you.
I highly recommend the book Effective Java, it contains a lot of useful information about how to write better programs in Java.
Your question is addressed in items 13 and 14 of that book:
Item 13: Minimize the accessibility of classes and members
Item 14: In public classes, use accessor methods, not public fields
You shouldn't allow implementations to alter your records directly. Providing getters and setters means that you have exact control over how variables get assigned or what gets returned, etc. The same thing goes for the code in your constructor. What if the setter does something special when you assign a value to size? This won't happen if you assign it directly.
It's a common pet-peeve of many programmers - Java code with private fields and public accessors and mutators. The effect is as you say, those fields might as well been public.
There are programming languages that voice for the other extreme, too. Look at Python; just about everything is public, to some extent.
These are different coding practices and a common thing programmers deal with every day. But in Java, here's my rule of thumb:
If the field is used purely as an attribute, both readable and writeable by anyone, make it public.
If the field is used internally only, use private. Provide a getter if you want read access, and provide a setter if you want write access.
There is a special case: sometimes, you want to process extra data when an attribute is accessed. In that case, you would provide both getters and setters, but inside these property functions, you would do more than just return - for example, if you want to track the number of times an attribute is read by other programs during an object's life time.
That's just a brief overview on access levels. If you're interested, also read up on protected access.
This is indeed used to hide the internal implementation. This also helps is providing extra bit of logic on your variables. Say you need to make sure that the value passed for a varable should not be 0/null, you can provide this logic in the set method. Also in the same way you can provide some logic while getting the value, say you have a object variable which is not initialised and you are accessing that object, in this case you cand provide the logic to null check for that object and always return an object.
C# programmers use this equally as much, or maybe more frequently than I see in Java. C# calls it properties where in Java it is accessors/mutators
For me it makes sense to have getter and setter methods to encapsulate the classes so that no class can change the instance variables of another class.
Okay. We are talking about Objects here. The real world objects. If they are not private,the user of your class is allowed to change. What if for a Circle class, and for the radius attribute/property of the Circle class, the user sets value as '0'. It doesn't make sense for a Circle to exist with radius as '0'. You can avoid such mistakes if you make your attributes private and give a setter method and in which and throw an Exception/Error (instructing the user ) that it is not allowed to create a Circle with radisu as '0'. Basically, the objects that are created out of your class - are meant to exist as you wished to have them exist. This is one of the ways to achieve it.
As stated earlier, the reason for making a variable private is to hide it from the outside. But if you make a getter AND a setter then you may as well make the variable itself public. If you find yourself later in a position that you made the wrong choice, then you must refactor your code from using the public variable into using the getter/setter which may not be a problem. But it can be a problem if other code, which you do not control, starts depending on your code. Then such a refactoring will break the other code. If you use getters and setters from the start you will reduce that risk in exchange for a little effort. So it depends on your situation.
It depends on who access these public variables. Most likely, only by people inside your company/team. Then it's trivial to refactor them into getters/setters when necessary. I say in this case, it's better to leave the variables public; unless you are forced to follow the java bean convention.
If you are writing a framework or a library intended for the public, then you shouldn't expose variables. It's impossible for you to change them into getters/setters later.
But the 2nd case is more rare than the first; people apply extremely unreasonable assumptions when it come to software engineer, as if they are not writing code, instead they are carving code in stone. And as if the whole world is watching while you code - in reality, nobody will ever read your code except yourself

Private variables/methods in anonymous class?

I have created an anonymous class in which I declare a few variables and methods. My java teacher tells me to make these private. I don't see how changing the modifier makes any difference since these variables and methods are private to the anonymous class anyway, so I prefer to have no modifier at all. Who is right and what makes more sense? See below for example code where I choose no modifier for 'map' and 'convert' rather than making them private.
Collections.sort(list, new Comparator<String>(){
public int compare(String a, String b){
return convert(a).compareTo(convert(b));
}
Map<String, String> map = new HashMap<String, String>();
String convert(String s) {
String u = map.get(s);
if (u == null)
map.put(s, u = s.toUpperCase());
return u;
}
});
I would be tempted to make them private simply for the fact that if you refactor the code and pull the anonymous class out as a standard class (Intellij, for example, can do this at the click of a button), having private fields is what you really want. You won't have to go and rework your classes to match your standard.
Personally I would make them private (and final where possible) anyway - it's just a good habit to be in in general.
To put it another way: if you had to put an access modifier on (if, say, the keyword package was also used as an access modifier) what would you choose? Private, presumably - after all, you don't actually want to grant any other class access, do you?
Now, having decided that private is the most logically appropriate access modifier, I would make that explicit in the code.
Then again, I'd quite possibly not create an anonymous inner class with a member variable anyway - I'd be tempted to turn that into a named nested class instead.
Your professor is right.
Make all class variable private and expose them via properties (if not anonymous).
The general rule of thumb is to keep member data such as variable including your Map object private.
Default modifier is not the same as the private modifier, there're subtle differences.
However, in your case it's more a religious question whether to make convert() default or private. I don't see any advantage in making it private though.
Anyway, your code has a memory leak as the String Cache is never cleared :-P
Also, for even shorter/less code, use the Comparator String.CASE_INSENSITIVE_ORDER:
Collections.sort(list, String.CASE_INSENSITIVE_ORDER);
It really doesn't matter, but it's probably a good idea to keep your teacher happy as he/she will be grading you.
I'd say it's a matter of style. You can't access the member map outside out of the anonymous class, but it might be best to define them as private for consistency with other classes.
If this were my code, I would say that if a class is complicated enough to need data members, it might be worth pulling it out into a separate class, in which case I'd certainly make the data members private.
The key point is when you say "I don't see how changing the modifier makes any difference since these variables and methods are private to the anonymous class anyway"... you're assuming a lot about how your class is going to be used. Treat every class like it will be passed around and used in a variety of ways, in other words, use modifiers as appropriate. Besides, it makes the intent of class clear. It's not like Java is a terse language anyway, so you might as well be clear.
I don't see much benefit to marking things private just for the hell of it. It won't really gain you anything and someone reading the code might attach some significance to the choice when there really isn't any.
I would question the need for all this complexity. Take a look at: String.compareToIgnoreCase()
You want these fields to be private, so mark them private.If a member is marked neither public not private then something suspicious is going on. Also mark fields that shouldn't change final. Keeping things standardised means less thinking, or at least less thinking on the irrelevant, and less to change when modifying code.
From a language point of view, the only real difference is that if you have extended a base class in the same package, you have now hidden fields or overridden "package-private" (default access) methods. The members can also be accessed via reflection (without setAccessible) by code in the same package (this can have mobile-code security implications).
difference between default and protected.
protected:
object/method is accessible to all classes that are in the same package, and also accessible to sub/extension classes.
default:
object/method is accessible to all classes that are in the same package.
What is your intention of your object/method and code modifier accordingly.
Do not allow yourself to be confused when you come back to the code after six months because in huge projects you want to know that that object/method is or is not accessed anywhere else.
In three weeks, not just months, you would forget what the intended accessibility of those objects, 101% guaranteed. Then if you had a huge project and you had a hundred modifiers that were not specific and you desperately wanted to update the code, you would be frustrated by the compulsion to run reference check on those 100 objects/methods. May be someone took your jar and found the hidden cookies in them and used them, then you changed your code and broke someone's code.
Code your modifiers according to your intention unless you are either one or more of these:
you have no further desire to work
in large java projects.
you are a
extremely intelligent high
functioning autistic person who has
an indexed memory of every event of
your life and can write a completely functional peer-peer file sharing service
within two weeks on a lap top in a
coffee shop.
you deliberately use it
as another tool to obfuscate your
code.

junit & java : testing non-public methods [duplicate]

This question already has answers here:
How do I test a class that has private methods, fields or inner classes?
(58 answers)
Closed 5 years ago.
JUnit will only test those methods in my class that are public. How do I do junit testing on the ones that are not (i.e., private, protected)?
I can test them by not using junit, but I was wondering what the junit standard method was.
One school of thought about unit testing says that you should only be able to test public methods, because you should only be unit-testing your public API, and that by doing so, you should be covering the code in your non-public methods. Your mileage may vary; I find that this is sometimes the case and sometimes not.
With that said, there are a couple of ways to test non-public methods:
You can test protected and package-scope methods by putting your unit tests in the same package as the classes they're testing. This is a fairly common practice.
You can test protected methods from unit tests in another package by creating a subclass of the class under test that overrides the methods you want to test as public, and having those overridden methods call the original methods with the super keyword. Typically, this "testing subclass" would be an inner class in the JUnit TestCase class doing the testing. This is a little bit more hacky, in my opinion, but I've done it.
As with many unit testing problems, testing private methods is actually a design problem in disguise. Rather than try to do anything tricky to test private methods, when I find myself wishing to write tests for private methods I take a minute to ask myself, "How would I need to design this so I could test it thoroughly through public methods?"
If that doesn't work, JUnitX allows testing private methods, although I believe it is only available for JUnit 3.8.
When you write a JUnit test, you have to do a subtle mind shift: "I'm a client of my own class now." That means private is private, and you only test the behavior that the client sees.
If the method really should be private, I'd consider it a design flaw to make it visible just for the sake of testing. You've got to be able to infer its correct operation based on what the client sees.
In the three years that have passed since I originally wrote this, I've started approaching the problem slightly differently, using Java reflection.
The dirty little secret is that you can test private methods in JUnit just as you would public ones, using reflection. You can test to your heart's content and still not expose them as public to clients.
The simplest solution is to put the JUnit tests in the same package (but different directory) and use default (i.e. package-private) visibility for the methods.
Another more complicated approach is to use reflection to access private methods.
If you have a significant amount of logic buried under relatively few "Public" entry points, you are probably violating the Single Responsibility Principle. If possible, you'll want to refactor the code into multiple classes, ultimately leading to more "Public" methods from which to test.
Here is the "probably shouldn't do it this way" method that everyone else keeps harping at you about. I think it's certainly within the realm of possibility that there are reasons for doing it this way, though. The following code will access a private field, but the code for a private method is nearly identical.
public void testPrivateField() throws InterruptedException {
Class<ClassWPrivateField> clazz = ClassWPrivateField.class;
try {
Field privateField = clazz.getDeclaredField("nameOfPrivateField");
privateField.setAccessible(true); // This is the line
// do stuff
} catch(NoSuchFieldException nsfe) {
nsfe.printStackTrace();
fail();
} catch(IllegalAccessException iae) {
iae.printStackTrace();
fail();
}
}
I've come across the same issue, and the "if it needs to be private it probably should be refactored" doesn't sit right with me.
Suppose you have sort of functionality that you want to separate out in some way internal to the class. For example, suppose I have something like this:
public class HolderOfSomeStrings{
private List<String> internal_values;
public List<String> get()
{
List<String> out = new ArrayList<String>();
for (String s:internal_values)
{
out.add(process(s));
}
return get;
}
private static String process(String input)
{
//do something complicated here that other classes shouldn't be interested in
}
}
The point here is that junit forces me to make process public, or at least protected, or to put it in it's own utility class. But if it's some sort of internal logic of HolderOfSomeStrings, it's not at all clear to me that this is correct—it seems to me that this ought to be private, and making it more visible gums up the code in some way.
I nearly always use Spring in my Java projects and, as such, my objects are built for dependency injection. They tend to be fairly granular implementations of public interfaces that are assembled within the application context. As such, I rarely (if ever) have the need to test private methods because the class itself is small enough that it simply isn't an issue.
Even when I don't use Spring I tend to adopt the same practices of assembling small and simple objects into larger and larger abstractions, each of which is relatively simple but made complex by the aggregated objects.
In my experience, having the need to unit test private methods is an indicator that what you're teesting could (and should) be simplified.
That being, if you still really feel the need:
Protected methods can be tested by subclasses;
Package private methods can be tested by putting the unit tests in the same package; and
Private methods can be unit tested by providing, for example, a package private factory proxy method. Not ideal but private does mean private.
You usually don't test private methods because they can only (normally) be tested indirectly through another public method. When you're test driving and make private methods then they are usually a result of an "extract method" refactoring and are already by then tested indirectly.
If you are concerned about testing a private method with lots of logic then the smartest thing you could do is to move that code into another class in a public method. Once you've done that, the previous method that used this code can have it's testing simplified by having the functionality provided by a stub or a mock.
To borrow a thought from Andy Hunt, even your private methods must have some side effect that you're interested in. In other words, they must be called from some public method and perform an interesting task that causes the state of your object to change. Test for that state change.
Suppose you have public method pubMethod and private method privMethod. When you call pubMethod, it in turn calls privMethod to perform a task (perhaps parsing a String). The pubMethod then uses this parsed String to set member variables' values in some way or to influence its own return value. Test by watching for the desired effect on pubMethod's return value or on member variables (possibly by using accessors to get to them).
DP4j Jar
For testing private methods we need to use reflection and its pointed in all answers.
well now this task is simplified with help of Dp4j jar.
Dp4j analyzes your code and automatically generates the Reflection API code for you.
Just add dp4j.jar to your CLASSPATH.
Dp4j.jar contains Annotation Processors, they will look for the methods in your code that are annotated with #Test JUnit annotation.
Dp4j analyze the code of those methods, and if it finds that you are illegally accessing private methods, it will replace your invalid private method reference with equivalent code that uses Java's Reflection API.
Get More details here
You can use TestNG instead of JUnit, which doesn't care about the method being private or public.
Use reflection as above to test private methods.
If we are following TDD we should test private methods given that TDD implies that there would be no surprises later.
So one should not wait to finish his public method to test privates.
And this helps in more granular regression testing upon re factoring.
Look for "PrivateAccessor.invoke". My code imports it from "junitx.util", but I don't know where it came from.
In agreement with just about every post--you should probably refactor and probably not test private except through public, just wanted to add a different way to think about it...
Think of your class itself as a "Unit", not a method. You are testing the class and that it can maintain a valid state regardless of how it's public methods are called.
Calling private methods can destroy the encapsulation and actually invalidate the tests.
As kind of an offshoot of this, and I'm not sure where everyone comes down on the whole "polyglot programming" issue, but Groovy tests are runnable in Junit, and ignore the whole public/non-public issue. Side note, it was officially classified as a "bug", but when they tried to fix it, there was such a storm kicked up about it that it was put back as it was originally.
I absolutely agree with #duffymo that code should be tested from the client's view ( though he says he quit thinking this way). However, from this point of view, private vs others have different meanings. Client of a private method is the class itself so I prefer testing them through the external (public/package-protected) API. However, protected and package-protected members are there for external clients, so I test them with fakes which inherit the owning class or which reside in the same package.

Categories

Resources