1

I know there are many question concerning unit-tests of private members within classes. Most of them come to the conclusion that having private members that need to be tested are a design-flaw that needs refactoring (e.g. see here). However I still have one last question:

When I refactor my private members to new classes they become (public) API-members however which I intended to avoid. So by simplifying our client class we polute our API by designing a new publicly visibly helper-class. Of course one might also write the test-code within the assembly and make those helpers internal but thus we´d also ship test-code to production-site.

I assume there is no right answer to this issue but perhaps you have some great ideas that help to avoid those situations?

Community
  • 1
  • 1
MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111
  • 2
    IMHO, don't break/pollute code for the sake of testability. I'd rather use reflection (like the link above) to test a private method to make sure nothing is breaking. It's "ugly"... but it works well. I'd rather have an ugly car that runs well, then a Ferrari which can explode any moment without warning. – Jaco Van Niekerk Aug 25 '15 at 07:45
  • I really don't see what is wrong with using reflection for unit testing. It is not production code you are messing with, and sometimes it just does make sense to unit test private methods. – John Aug 25 '15 at 07:45
  • I recommend not to test private methods. Test them through public api. See https://lostechies.com/chadmyers/2008/11/21/do-not-test-private-methods/ – Sriram Sakthivel Aug 25 '15 at 07:55

2 Answers2

2

Regarding C# there is one last trick you could try

  1. Make your class/members internal
  2. In the assembly to test, open the AssemblyInfo.cs file and make the internals visible to your Test-Project/Assembly by adding the following attribute:

[InternalsVisibleTo("YourTestProject")]

This makes you members invisible outside your assembly, except for the sake of test within the "YourTestProject"-Assembly.

More info on this Attribute can be found on MSDN.

nozzleman
  • 9,529
  • 4
  • 37
  • 58
  • Whilst this doesn´t polute the API it still changes the actual class-design by widening the acces of its members just for the sake of testing. However I guess this is ok in most scenarios. – MakePeaceGreatAgain Aug 25 '15 at 07:47
0

I planned to write this as an edit but I come to the conclusion that I made whrong assumptions on the questions. I think my problem is that I mix WHAT to test with HOW to test it.

WHAT to test: members that do a certain amount of work that is worth to be tested. Access-modifier does not play any role here.

HOW to test: no problem on public members; however on private members a bit tricky, but doable as seen on nozzlemans answer above.

Having said this the correct approach would be to extract the relevant members to new non-public helper-classes. To be able to test those members although not public we use any of the previosly mentioned approaches, reflection, InternalsVisibleTo or even private accessors (which use reflection at some point).

MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111