I think, therefore I blog

How To Unit Test Private Methods

By , 19 September 2012

How To Unit Test Private Methods
How To Unit Test Private Methods

I've discovered that one reason I don't write as many unit tests as I should is because they live in a separate source tree, out of sight and out of mind. So I've moved my unit tests to be inner classes on the classes they test. A side effect of this is you can easily test the private methods of a class since the inner class has direct access to these methods.

Here is the configuration you will need to do this. Note, I am using TestNG, but it should be pretty similar in JUnit.

How To Unit Test Private Methods

By default surefire will not execute tests in inner classes so first you need to fix this and also tell maven where your test code is by adding this to your <plugins> section:

    <!-- unit tests live inside the java source files themselves -->

Note that [none] is not a special keyword, it only exists to match no class files. You can put whatever rubbish in there (but a blank entry has no effect).

Your unit tests must be public static inner classes annotated with @Test, like this:

    public static class UserEditorTest {
        public void test_private_method() {
           assertEquals(new UserEditor().somePrivateMethod(), "success");

Since the test class is an inner class, it can call the private method.

To run the test from maven, I use a wildcard on the test name so I don't have to specify OuterClass$InnerClass.

    $ mvn test -Dtest=*UserEditorTest

To get Netbeans to run the tests, you can use a wildcard so it finds the inner class. Go to the project properties and look for the Actions settings. You will need to set the parameters like this:


You can also run from a normal testng.xml test suite like this:

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite1" verbose="1">
  <test name="MyTest" >
       <class name="com.example.Example$ExampleTest"/>

This setup has improved my productivity and (more importantly) the coverage of my unit tests. Do you think using inner classes for unit testing is a bad idea? Let me know why in the comments below.



About Roger Keays

How To Unit Test Private Methods

Roger Keays is an artist, an engineer, and a student of life. Since he left Australia in 2009, he has been living as a digital nomad in over 40 different countries around the world. Roger is addicted to surfing. His other interests are music, psychology, languages, and finding good food. Click here to subscribe to his weekly blog, or stalk him on Facebook and Twitter.

Leave a Comment

Please visit https://RogerKeays.com/how-to-unit-test-private-methods to add your comments.

Comment posted by: Guus Bloemsma, 3 years ago

 Another advantage of using inner classes is having access to private members. This way you can avoid making members non-private just to test them.

Inner classes used to be the default way of testing in NetBeans. Unfortunately conventions are different now.

Comment posted by: , 4 years ago

Whatever works best for you of course... I'm hooked on embedding tests everywhere now. Even in shell scripts and config files. I also see shipping tests as an advantage. It's like opening the hood of your car and having a description of what each component is supposed to do and how to test it. I once had a hot water system like that and it saved me a cold shower or ten.

Comment posted by: Tomek Kaczanowski, 4 years ago

I have to say I'm surprised that you see a problem with test kept in parallel source tree. Current IDEs let you navigate easily from production code to tests (provided that you stick to the most popular naming pattern of test classes).

The price you have to pay - mixing test code with production - is not acceptable for me.

Comment posted by: , 4 years ago

Executable examples. That's pure genius.

Comment posted by: Drew, 4 years ago

One of my favourite examples of keeping the unit tests near the tested code is Python's doctest. You essentially have examples of calling the function in the function comments and doctest will run them to make sure they're valid!

Comment posted by: , 4 years ago

Hi Vlad,

You can do that by just removing the class files that match *$*Test.class. Something like this in shell:

$ rm `find target -name "*$*Test.class"`

But I actually like the fact that my code is shipped / deployed with all my tests. They only take up a fraction of the space of all my bundled libraries and you never know when they might come in handy.

Comment posted by: Vlad, 4 years ago


Do you have any way to filter out the test classes from the deliverable jar? Leaving them there means a lot larger archives.

regards, Vlad

Join Over 1000 Subscribers

I write every Sunday about travel, psychology, and technology. Thousands of people just like you have already subscribed—and for good reason. It'll change your life. And it's free :)

Read a Good Book

“A spellbinding true story of love, passion and adventure. One can’t help but be swept away by 100% Love Guaranteed.” —Dr Tammie Matson, author of Elephant Dance.

Chat For A While

Your Vote Matters

Which animal will take over when humans go extinct?