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.
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.
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.
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.
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.
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.
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.
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();
}
}
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).
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.
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.
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.
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.