3

In MSTest, the [Shadowing] attribute helps you to unit test a private method from another assembly. Here is the related link : What is the Shadowing attribute that the VS uses when it generates unit tests?

My questions are:

  1. Should private methods be unit tested separately?
  2. Is it a good (?) practice to change private method's accessor to internal just to make it available for unit testing in some other test project/assembly? (using InternalsVisibleTo)
  3. If private methods get tested indirectly through the public method that calls them, can it be called "unit" testing?
Community
  • 1
  • 1
Learner
  • 4,661
  • 9
  • 56
  • 102

4 Answers4

4
  1. No, private methods should not be tested. Your application will interact with public API only. So you should test expected behavior of your class for this interaction. Private methods is a part of inner logic implementation. Users of your class should not be care how it implemented.
  2. No, it is not good. See above. You should test public API only.
  3. You should test only public methods. You don't care if public method will call to private method or will not until test is passed. If test fails, fix implemetation. But don't test private methods anyway.

UPDATE (how to define what to test): Ideally (in test-first approach) test is the first user of your class. When you write test, you try to imagine how users will use your class. Users will not interact with private methods (Reflection is cheating). So and your test, as first user of your class, should not interact with private methods.

Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
  • 2
    Last I checked, *unit* testing was *not* about testing the parts that users see. On the contrary, it is about testing individual parts of the implementation. – jalf Mar 23 '12 at 10:19
  • By user of class I mean class consumer (another class). Definitely not human. – Sergey Berezovskiy Mar 23 '12 at 10:24
  • But again, I'm not convinced that you're really *unit* testing if you only test the public interface. It may rely on a fair amount of (private) implementation, which one would like to isolate for testing purposes – jalf Mar 23 '12 at 10:29
  • Class responsiblities described only by its public interface. Consider of class with NO public interface. Would you write tests for that class? – Sergey Berezovskiy Mar 23 '12 at 10:37
  • No, I'd delete the class. But again, to me it would seem like if you only test the public interface, it's functional testing, not unit testing. You're testing that the class delivers the promised functionality. Unit testing is about testing each individual step in that process, so that if part of it breaks, you know exactly what broke, and where. So to my mind, that would imply that (ideally) unit testing should also be done on the (private) implementation details. But this is just thinking out loud. I've heard recommendations go either way, not sure if there is a single "correct" answer – jalf Mar 23 '12 at 11:36
  • @jalf Hey! I know this is a late reply, but I have a quick response in regard to testing private methods. Typically if the private methods of a class are so complicated that they too need testing, then it usually (not always) implies that your class is carrying a lot more functionality and responsibility than it should have and should probably be pulled out into another class. It's all about testing input and output, and if the class is so complicated that there are parts that you feel are private and need their own testing, then the class could possibly rely on another class to do it. – Anther Oct 03 '12 at 20:11
  • But isn't the point in unit testing that there is no part that is "too small"? You explicitly set out to test the smallest possible parts. And so, any time you're skipping a private method, and only testing the public interface of a class, you're no longer *unit* testing. Unit testing, at least as I understand the term, is not about testing parts that are "so complicated they need testing". It is about testing the simplest, smallest *units* that your program is built from. – jalf Oct 03 '12 at 21:05
2

To answer your questions briefly:

  1. In general, they shouldn't. Most of the times, your private bits will be tested while testing class contract/public API. For the times this is not possible, testing private method is unit test just as anything else.

  2. This is fairly common. While changing visibility might be considered bad idea, it's not as bad when it changes only to internal. However, in approaches like TDD, the need of testing usually drives your desing in such way that "hacks" like this are not needed. But like I said, it's fairly common - you shouldn't worry too much about it, unless it gets to ridiculous levels (say, entire private parts of classes exposed).

  3. It is unit test as long as it tests single unit (or, one logical concept) of your class. Private methods more often than not are created as a results of refactorings in public parts, which most of the times will be targeted by the single unit testing. If you feel your private method is not longer an unit, it might be a refactoring call.

Also, I suggest having a look here, here and here.

Community
  • 1
  • 1
k.m
  • 30,794
  • 10
  • 62
  • 86
1

I would preffer to exercise all the private methods thru the public available calls. There must be a path to execute each private line from a public call and if it is not there you can delete that code.

Using internal instead of private could end with a big mess, I won't use that approach.

Ignacio Soler Garcia
  • 21,122
  • 31
  • 128
  • 207
0

As a Java developer, I do. I don't change access levels, either. I use reflection to get access to private methods. I don't have to grant it to my users, and I don't have to show them my unit tests.

It's a dirty secret of Java: you can always circumvent access restrictions with reflection. I don't know if it's also true of C# and .NET, but you can look into it to see.

duffymo
  • 305,152
  • 44
  • 369
  • 561
  • But, why do you need to test private methods directly instead of testing them thru the public methods? – Ignacio Soler Garcia Mar 24 '12 at 09:44
  • Why? Sometimes I really want to know how that method behaves. I understand the dogma about "only test through the public API", but like all extreme positions I think there are logical exceptions. – duffymo Mar 24 '12 at 11:08
  • At the end it does not matter if that method behaves badly in a way that cannot be reached thru the public API. But anyway, I see your point too. – Ignacio Soler Garcia Mar 24 '12 at 14:38
  • No, I don't agree. It certainly matters, even if the public can't 'reach' it. Private methods are called by my class implementation, so eventually they affect what the public sees. Otherwise what's the point of writing them? Testing private methods narrows your objective down to make sure that your implementation is correct. As a developer, that's always my responsibility. I don't allow dogmatic positions to prevent me from fulfilling my obligations. If testing private methods helps me to do it, then damn convention. – duffymo Mar 24 '12 at 15:30