Test Driven Development: Testing Private Methods Using Aspect Oriented Programming
Recently, I have been working on a project that can be considered my first real test driven development experience. As the name implies, test driven development is an agile methodology that aims at producing code that has been fully tested. Another one of the most powerful advantages of test driven development is that if a developer modified the code, he can easily run the existing test suits and he would know if his modification broke any of the existing features in the code. Essentially, a developer starts thinking of the functionality that needs to be added to the existing code base. Then, before writing any code, he writes a test case (maybe a number of them) that will of course fail because the feature isn’t implemented yet. Then he would write the bare minimum code that would make the test cases pass. Then write more tests, then write more code to pass the tests …etc.
So, what’s the problem? Well, one of the main problems with Test Driven Development is testing private methods (assuming that you’re using an Object Oriented language). I googled the problem, and I found a number of solutions. Here is a list of the interesting ones along with the problems of each:
- Change the access modifier of the method to public/protected/internal/…etc., run your tests, then change it back to private
- Once you change the access modifiers back to private, your test cases won’t even compile.
- If I decided that a specific method needs to be private, why would I ever want to change it to public. It seems like a dirty walk around the problem and violation to the developer’s intended design.
- Philosophical solution: Test only public methods, which are assumed to call private ones.
- It is based on the unsolved debate of what unit testing really is.
- It sounds like “lets ignore the problem intentionally”
- If you’re using JUnit4, you can create your test cases in the same class you’re testing, which means you have access to its private methods.
- It results in a large sized release of your project. Because you have all test cases embedded in your code.
- What if your test case needs to test two private methods separated in two different classes?
- Use annotations/attributes/…etc.
- It isn’t a language independent solution
- Behind the scenes, these annotations change the accessibility of your methods. But again, this implementation is different in each language.
- I’d appreciate it if anyone shares any other solutions?
Luckily, I was able to find another solution that seems to satisfy my requirements. Although the solution is generic and language independent, I’ll explain it referring to Java. Before we go on, let me give you a quick introduction to the technologies that I used.
Aspect oriented programming is a technology intended to motivate separation of concerns. Usually developers refer to concerns as features that can be, but not necessarily, tied to the business logic. For example, logging, caching, exception handling, …etc. However, I think that it is safe to look at concerns as any feature that is required in your program. One of the most powerful tools that aspect oriented programming provides is called introduction. Basically, it means that you can introduce new fields, methods, or structure to your existing classes, which is the core tool behind my solution. [Have you guessed the solution yet?] Most language compilers have aspect oriented programming extensions. For example, AspectJ is one of the most common Java extensions that supports aspect oriented programming.
Alright here is how you can unit test private methods using aspect oriented programming:
- Create aspects that introduce public methods to the class under test
- In those public methods, you have access to all private methods and fields, call the private method and return the result.
- In your unit test, call the public method which is just a simple wrapper to the private method.
- Once your program is mature and ready to release, all you have to do is to build the source code without both of unit tests and AspectJ files.
Is it the best solution in the world? I don’t think so, and here is why:
- If I ever wanted to release my test cases as well as my source code, I have to ask other developers to install a new compiler, because the test cases won’t compile without applying (weaving) the aspects into the code base. In my case, the compiler is AspectJ.
- Developers in my team have to learn a new language constructs (aspects). However, I have to say that you can learn it in less than an hour. Probably, not master it
.
Note: if you know of anyone that proposed this solution, please let me know so that I give him the credit for the idea. Also let me know if you’d like any sample source code to demonstrate the idea.
Please, share your thoughts!

One thing that we need to be cautious of when doing TDD is that we do not want to change the interface to our classes to facilitate testing. For this reason doing something like changing a private method to public purely so you can test it is just plain wrong.
What I’ve been doing to get around this problem (in .net so I’m not 100% it will work the same in Java) is this…I create a public ‘nested’ class called ‘Testing’ that has public static methods with the first parameter being the type it is nested in (if I need to access non public methods). From this nested class I can access all of my private methods, properties etc.
For example:
public class Foo
{
private string name;
// Testing Use only
public class Testing
{
public static string GetName(Foo foo)
{
return foo.name;
}
public static string SetName(Foo foo, string newName)
{
foo.name = newName;
}
}
}
Yes I have changed my interface for testing but only by adding one thing which is clearly for testing use only and that one thing neatly wraps up all of the methods I need to support testing of that class. Developers who use these methods for system code get sacked
If all of your classes have this internal class then developers always know where to find ‘helpers’ for testing…and where to put helper methods.
Is it the best approach? I think all approaches have their pro’s and cons but this way works nicely for me
(note…not my idea originally)
Mark,
It is definitely an interesting approach. I usually do whatever suits the task at hand. I don’t think that there is a generic solution for this problem that fits all scenarios.
Thanks for sharing your thoughts!
How to test private methods? This question comes up a lot but I just don’t get it. What test drove you to write a private method in the first place? In my experience private methods pop out of the refactoring stage and are adequately covered by the existing tests. Of course at some point in the future a test I write might need the functionality in that private method, at that point it will get hoisted in to the public interface of some class and have appropriate tests.
It almost always seems to me that a class with more than a couple of private methods is really more than one class and those private methods are really public methods on some other class.
Clark,
I agree with you that in TDD, you’d have to have a test case that would drive you to write your private methods.Although this is somehow debatable depending on the situation. However the question “how to test private methods?” is applicable for any unit testing practices whether or not it is TDD.
The question is what private methods to test? I have had a lot of answers to this question and all of them boil to that we should test private methods that have more than one path of execution and we need to test different paths, private methods that are complex enough not to be covered by one test scenario, and private methods that may or may not be executed by public ones.
As for the importance of private methods, I am actually curious what couple of private methods would make the cut with you? For me, there are multiple reasons for private methods.
1) code simplicity, reusability, …etc.
2) API management and restrictions
3) Private variables control
…
Thanks for sharing your thoughts!
Using aspects is surely original idea. I think you didn’t mention it’s also possible to use reflection to test private methods and check state of private fields.
I personally prefer making fields package-private since this doesn’t affect public interface of the class and allows methods to be called in unit test (assuming it’s located in the same package).
I can’t imagine a test that would drive me to write a private method, it would drive me to write a public one. A private method might come about as a refactoring, removal of duplication or as a means of better expressing the code’s intent.
Private says to me “untested in isolation”, if I get the urge to test this method in isolation I then ask myself why I want to do this and realize the code is probably trying to tell me something. Normally this means that there is a lack of cohesion and other classes are trying to break out and further refactoring is in order.
I normally only end up with private methods that are there for code clarity/duplication removal reasons. These are exercised perfectly by the tests that test the behaviour of the class under test. All others tend to migrate into the public interface of some other class and become easy to test.
I would suggest you to read Michael Feathers’ wonderful article about the synergy between testability and good design.
http://michaelfeathers.typepad.com/michael_feathers_blog/2007/09/the-deep-synerg.html
Or, maybe not… Chances are you will regret having written this post.
Martin,
As for Michael Feather’s article, I think it is interesting. However, I think that “your design will improve if you aim for testability” is something that we all know and agree upon once you start using TDD
. Right? The only problem is that your design improves over longer periods of time, which is debatable and out of scope. The scope of my post is to show you a new tool to use for testing private method if you need to.
I’d like also to expand our vision here to multiple purposes behind unit testing. For example, code coverage in which you might need to unit test specific paths in private methods.
Note: I don’t regret things easily (if ever)
. We learn from our experiences and from nice people like you sharing their thoughts
.
I think what both Michael Feathers and I are trying to say is that testing a private method is only treating a symptom of the real problem, we should be fixing the real problem i.e. the lack of cohesion in the design.
In Java at least, there are multiple implementations you can find of a PrivateAccessor class that can modify private fields and invoke private methods on an object.
The biggest issue I have is that you normally don’t test drive private methods at all. You are testing the behavior of your object and that behavior is defined by the public parts of that object. Basically, you write a test (red), you implement it (green), and then you remove duplication or increase clarity by pulling parts of your public methods out to private ones (refactor).
I agree with the anti-private testing camp. There are ways in .NET to use reflection to gain access to privates which are pretty slick. In almost all cases (except for cases where driving the GUI is involved), I consider this to be bad practice.
If there is code in a private that a public method cannot hit via a unit test, it is probably dead code and should be removed. If that code is necessary, but you can’t test it, then you probably need to re-think your design.
Unit tests, in my opinion, are used to test and hold up the design of the code you are testing. Your assumptions and requirements for the unit are baked directly into the tests. They test behavior and privates do not expose behavior… publics do. In TDD, privates are just refactorings of the public behavior.
I have been doing TDD for over a year now, and I have been successful in writing full test suites for units without testing privates.
I agree, it is a matter of philosophy… a debate that needs to keep happening. Without it, we will remain stagnant.
Cheers!
This is a really interesting blog post,I have added your blog to my bookmarks I really like it,keep up the good work!
Khaled, the web is full of descriptions on how to test private methods in java, and the solutions (e.g. reflection API) are much simpler than using AspectJ (how many developers know AspectJ ? how many will understand your tests ? IMHO simplicity of test code is crucial), so why bother with such a big cannon here ? I don’t understand why you propose such a weird solution with no real advantage over other existing ones.
Tomek
How to test private methods? This question comes up a lot but I just don’t get it. What test drove you to write a private method in the first place? In my experience private methods pop out of the re factoring stage and are adequately covered by the existing tests. Of course at some point in the future a test I write might need the functionality in that private method, at that point it will get hoisted in to the public interface of some class and have appropriate tests.The question is what private methods to test? I have had a lot of answers to this question and all of them boil to that we should test private methods that have more than one path of execution and we need to test different paths, private methods that are complex enough not to be covered by one test scenario, and private methods that may or may not be executed by public ones. I normally only end up with private methods that are there for code clarity/duplication removal reasons. These are exercised perfectly by the tests that test the behavior of the class under test. All others tend to migrate into the public interface of some other class and become easy to test..I am hoping the same best work from you in the future as well.In fact your creative writing abilities has inspired me to start my own word press blog now. Really the blogging is spreading its wings rapidly.Your write up is a fin example of it.
Tomek,
Thanks for you comment. I agree with you that there are plenty of solutions (hacks) to this problem. So, you can think of this one as yet another solution that leverages relatively new technologies such as Aspect Oriented Programming.
As comparing it to reflection, I don’t think that reflection is any simpler. However, I have to say that reflection gives you one of the same advantages which is testing private methods without adding any code to your code base. Yet in both cases, tests will be clear to understand and so forth — maybe not as clear as other approaches.
Side note: I don’t think that because there aren’t that many developers that know AspectJ, we should ignore what AspectJ can do for us
.
I am just sharing my basic knowledge and some of my thought.