12

I recently noted that adding [TestInitialize] to a protected method in a .NET assembly wasn't respected, but if I made the method public it was called by the unit test runner (Resharper in this case). I've noticed this several times in the past with test methods.

Technically speaking, its just as easy to reflect on a private method as a public method. As a matter of fact, reflection is a method employed to unit test private methods.

So why do I need to make all my unit test methods public?

  • 2
    That's a really good question. The only good argument I've heard is that it follows the principle "program to an interface, not to an implementation," part of the SOLID principles. – Robert Harvey Aug 11 '15 at 15:03
  • 9
    I don't think he's talking about testing his classes, he's talking about the actual test methods that are called by test framework. – jtiger Aug 11 '15 at 19:59
  • 1
    @RobertHarvey in Java, reason for similar restriction (eg in JUnit) is that framework designers don't want to mess with setAccessible which can be blocked by some custom SecurityManager – gnat Aug 11 '15 at 21:12
  • 1
    you need to take in account that this design decision was made for a general purpose framework targeted for wide usage. In cases like that it's just safer for designer to assume and prepare to the worst. If it was, I don't know, some company-internal framework (where one can have chance to guarantee desired security policies), or if it was some tool of narrow, specialized purpose (think "viewer for inaccessible members"), designer would have other options to consider – gnat Aug 12 '15 at 13:58
  • 2
    @GregBurghardt This behavior is found in Nunit, and probably other test frameworks Microsoft didn't write. Sure in the years since asking this question I understand a lot more about .NET, but I still think its a fair question, and there is some good discussion in the comments. – Justin Dearing Jun 28 '18 at 18:47
2

You should Test what the class does, not how it does it.

As far as the "Outside World" is concerned, that's whatever the class makes Publically available; your Testing framework is making the same assumption.

By testing anything "less" than Public, you're delving into the class' internal implementation, which is a Bad Idea.

  • Note that the question is about the test methods, and not the methods in the system under test. While it is true that OP argues that you can use reflection to test things "less" than public, it is an argument about the ability of test frameworks to access private methods. The test framework has to use reflection to find the test methods (that are marked by an attribute), and thus must use reflection, with that in mind... "why do I need to make all my unit test methods public?" – Theraot Jun 29 '18 at 10:45
  • Test methods have the ability to access private methods; with Reflection, anything is possible. I see this question more about the [un]desirability of doing so. – Phill W. Jul 2 '18 at 10:18
0

As a general rule, it's best to only access public methods - when you create a class, you're also creating the contract as to which other classes should access your code. So the answer is most likely just because it's a convention.

  • 1
    This doesn’t really answer the question. – RubberDuck Mar 10 '18 at 10:02

protected by gnat Aug 13 '15 at 12:11

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.