If you mean private the way I think you mean it, then no - you shouldn't be unit testing it. You should only be unit testing observable behaviour/state. You may be missing the point behind the "red-green-refactor" cycle of TDD (and if you're not doing test first then the same principle apply). Once the tests are written and passing you do not want them to be changing whilst performing the refactoring. If you're forced to unit test private functionality then it probably means that the unit tests around the public functionality are flawed. If it's difficult and complex to write tests around the public code then maybe your class is doing too much or your problem isn't clearly defined.
Worse, over time your unit tests will become a ball and chain slowing you down without adding any value whatsoever (changing implementation, for example optimisation or removal of duplication, should have no effect on the unit tests). Internal code should, however, be unit tested as the behaviour/state is observable (just in a restricted way).
When I first did unit testing I pulled all sorts of tricks to unit test private stuff but now, with a few years under my belt, I see it as worse than a waste of time.
Here's a bit of a silly example, of course in real life you would have more tests than these:
Let's say you have a class that returns a sorted list of strings - you should check that the result is sorted, not how it actually sorts that list. You could start your implementation with a single algorithm that just sorts the list. Once that's done your test doesn't need to change if you then change your sorting algorithm. At this point you have a single test (assuming that the sorting is embedded in your class):
- Is my result sorted?
Now say you want two algorithms (perhaps one is more efficient in some circumstances but not others), then each algorith could (and generally, should) be provided by a different class and your class picks from them - you can check this is happening for your chosen scenarios using mocks, but your original test is still valid and as we are only verifying observable behaviour/state it doesn't need to change. You end up with 3 tests:
- Is my result sorted?
- Given a scenario (let's say the initial list is almost sorted to begin with) is a call made to the class that sorts strings using algorithm X?
- Given a scenario (the initial list is in a random order) is a call made to the class that sorts strings using algorithm Y?
The alternative would have been to begin testing private code inside your class - you don't gain anything from this - the above tests tell me everything that I need to know as far as unit testing is concerned. By adding private tests you're building yourself a straight jacket, how much more work would it be if you not only checked that the result was sorted but also how it's sorted?
Tests (of this type) should only change when behaviour changes, start writing tests against private code and that goes out the window.