Testing private classes in Java
Posted on September 1, 2007
Filed Under Uncategorized | 10 Comments
When you’re doing test driven development you often run into the issue where you want to test package level classes and/or private/protected/package level methods on classes. So what do you do? Either you open up your design to make them testable or you use JUnitX. Given that I don’t think it is a good idea generally to over expose yourself in public, I tend to go with JUnitX. Better for you. Better for me
Here’s what my test code looks like (which lives in its own unique test package):
public class MyTest extends PrivateTestCase
{
….
public void testPrivateMethodCall() throws Exception
{
// where Coffee is a private class within the package
Object privateClass = newInstance(”com.cognifide.cafe.Coffee”, NOARGS);
// AND drink is a private method on Coffee
invoke(privateClass, “drink”, NOARGS);
}}
Unfortunately, it is a bit quirky, and you have to create a boiler plate TestProxy class in the package for all classes that you want to test in this way. But I’ve taken a look at the source and you can get round this by tinkering with junitx.framwork.TestProxyFactory.createProxyFor(). I just haven’t got round to doing it. If you do, please drop me a line and send me your patch…
Comments
10 Responses to “Testing private classes in Java”
Leave a Reply


Why do you need to test private methods? Usually we want to test overall usability of a class, so it means to test against interface methods it implements. Am I right or this scenario applies only to perfect world?
In you’re perfect world you only every test against interfaces, but implementation classes tend to be a little trickier.
How do you unit test those to the level that you’re confident with? How do you test your private helper methods on this implementation class? Yes, you could do it indirectly through a higher level abstraction, but to me that is not unit testing the implementation class directly.
If I can write a test that tests the helper method directly, then i would prefer to do that, rather than some interface, that will call through to my private methods, doing who knows what before and/or after the call…
The question is if I really need to test such ‘private helper methods’.
How about:
- moving such private methods to some utility class
- making them protected to allow testing and reusability in future?
Of course everything depends on implementation, probably your approach is correct. However I have to admit I never need to test this way.
So you would prefer to artificially break up a perfectly good class to make it testable? So would I. But if there are tools around that enable me to maintain my design and keep it testable, i suppose i’d do that.
I not really hung up on keeping this private. Keeping things testable is more important…
I don’t mean to be overly harsh here, but anyone who feels the need to test private methods really hasn’t gotten to grips with TDD yet.
ha ha ha.
how funny merlyn. i would have expected nothing less from a purist.
anyway, strange as it seems, this discussion came up at a conference I attended and the room was divided from people that have been doing TDD for many years (more so on the private method side). People i kind of respect as well.
I don’ think it is as clear cut as ‘if you test private, you haven’t got TDD. That’s the sort of think that makes my skin shudder in a similar way when I hear agile folks say, if your projects failing, you not doing agile right.
pragmatically, on projects, i don’t think its a black and white as you’re painting it…
Yes, I guess it probably is the purist line too.
What reaffirms it for me though is that I haven’t found myself wishing I could test a private method since I was very new to TDD.
In fact I don’t see how you can arrive at the idea of even wanting to testing a private method with TDD. What would the thought process look like?
The way I’m assuming the situation arises would be something along these lines (when someone is only really paying lip service to their tests as opposed to being driven by them):
You’re writing your tests last and then it becomes apparent that you have some significant logic that’s used by more than one method you want to test, and because it’s all so unwieldy to tackle the problem all in one go now that you “have the code working anyway” the inclination is to work around the design problem by making your test dive into the internals of the class.
Ok. There’s another possibility which would then come down to personal design taste: Your design philosophy prohibits you from extracting behaviour from a class because then it would become visible to users of your package which you consider to be a bad thing.
In that case I’d take issue with the design approach and not so much the testing of private classes / methods.
Nope. I said I was not anal about encapsulation. It would be more important for me to know that stuff was testable.
Also, for integration and/or migration projects, where you don’t have complete control over code base and you are working with third party assets and the like, such tools are useful.
I most certainly am not a purist, more pragmatic and ultimately delivery focussed I suppose…
Here are two different opinions on the topic from the XPDX discussion group:
Ward Cunningham (http://tech.groups.yahoo.com/group/xpportland/message/1201)
“No, I’ve never had this problem [of wanting to test private methods].”
Jim Shore (http://tech.groups.yahoo.com/group/xpportland/message/1204)
“It comes down to a tension between the desire to TDD and the desire to follow a strict access model. One approach is to ignore the access model and just make things public when you need to test them. I prefer not to do that because the access keywords (public/private/etc) provide hints to future programmers about the my thought process. Still, I’ll do it when I have to.”