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?

4 Answers 4

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.

Sign up to request clarification or add additional context in comments.

7 Comments

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.
By user of class I mean class consumer (another class). Definitely not human.
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
Class responsiblities described only by its public interface. Consider of class with NO public interface. Would you write tests for that class?
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
|
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.

Comments

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.

Comments

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.

4 Comments

But, why do you need to test private methods directly instead of testing them thru the public methods?
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.
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.
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.