Look, there's no easy way to do this. I'm working on a project that is inherently multithreaded. Events come in from the operating system and I have to process them concurrently.
The simplest way to deal with testing complex, multithreaded application code is this: If it's too complex to test, you're doing it wrong. If you have a single instance that has multiple threads acting upon it, and you can't test situations where these threads step all over each other, then your design needs to be redone. It's both as simple and as complex as this.
There are many ways to program for multithreading that avoids threads running through instances at the same time. The simplest is to make all your objects immutable. Of course, that's not usually possible. So you have to identify those places in your design where threads interact with the same instance and reduce the number of those places. By doing this, you isolate a few classes where multithreading actually occurs, reducing the overall complexity of testing your system.
But you have to realize that even by doing this, you still can't test every situation where two threads step on each other. To do that, you'd have to run two threads concurrently in the same test, then control exactly what lines they are executing at any given moment. The best you can do is simulate this situation. But this might require you to code specifically for testing, and that's at best a half step towards a true solution.
Probably the best way to test code for threading issues is through static analysis of the code. If your threaded code doesn't follow a finite set of thread safe patterns, then you might have a problem. I believe Code Analysis in VS does contain some knowledge of threading, but probably not much.
Look, as things stand currently (and probably will stand for a good time to come), the best way to test multithreaded apps is to reduce the complexity of threaded code as much as possible. Minimize areas where threads interact, test as best as possible, and use code analysis to identify danger areas.
Some 10 years later perhaps the best way to test a private method, or any inaccessible member, is via
@Jailbreak from the Manifold framework.
@Jailbreak Foo foo = new Foo();
// Direct, *type-safe* access to *all* foo's members
foo.privateMethod(x, y, z);
foo.privateField = value;
This way your code remains type-safe and readable. No design compromises, no overexposing methods and fields for the sake of tests.
If you have somewhat of a legacy Java application, and you're not allowed to change the visibility of your methods, the best way to test private methods is to use reflection.
Internally we're using helpers to get/set
private static variables as well as invoke
private static methods. The following patterns will let you do pretty much anything related to the private methods and fields. Of course, you can't change
private static final variables through reflection.
Method method = TargetClass.getDeclaredMethod(methodName, argClasses);
return method.invoke(targetObject, argObjects);
And for fields:
Field field = TargetClass.getDeclaredField(fieldName);
TargetClass.getDeclaredMethod(methodName, argClasses) lets you look into
private methods. The same thing applies for
setAccessible(true) is required to play around with privates.
Unit Testing (UT) != Test Driven Design (TDD)
This confusion seems to be fairly common. UT is all about code coverage. TDD is concerned with features. They are not the same thing [sorry Joel!]
With UT, you write whatever code you want to, then go back and test every single function (even some of the trivial ones).
With TDD, you select the next feature and write the test for that feature first. Write only the test for that feature, and test coverage is irrelevant. You write the test first to force interface decisions to be made up front. Then you write the code to pass the test (bearing in mind the 'simplest thing that can possibly work'). Then you refactor the code based on what you've learned. Then you go on to the next feature (presumably after check-in and re-running all unit tests).
If desired, develop using TDD then go back and complete coverage with UT tools. If you're creating a class library or other API for developers to use, the more test coverage the better ;-)
If you're just writing an app to do five specific things, TDD alone should be sufficient.