Ik ben een groot fan van automatische testen en van de gedachtes achter test driven development. Tegelijkertijd zie ik collega’s vaak worstelen met het maken van keuzes met betrekking tot welke methodes ze wel, of juist niet opnemen in testen. Van mij mag je doen wat je wilt, maar ik zal proberen uit te leggen waarom ik private methoden niet apart test.
Hoe zit het ook alweer met de access modifiers?

Voordat ik in ga op testen, neem ik je mee naar de betekenis van de verschillende access modifiers: private, internal en public. In de context van een object georiënteerde omgeving wil je duidelijke encapsulatie van logica in objecten. Een belangrijk onderdeel van die encapsulatie is dat duidelijk is welke onderdelen van de code public zijn, welke internal zijn en welke methodes private zijn. Publieke en internal methodes zijn hierbij bedoeld om van buiten het object zelf gebruikt te worden, terwijl de private methodes bedoeld zijn om structuur binnen het object zelf aan te brengen.
In mijn beleving is het belangrijk om je code zodanig te structureren dat voor een gebruiker van je code (ook als je dat zelf bent) duidelijk is welke functies of eigenschappen hij mag gebruiken. Als je een library maakt, betekent dit in mijn perspectief dat alleen public is, wat ook daadwerkelijk bedoeld is om van buiten de library te gebruiken. Ik zie in de praktijk dat er vaak te weinig wordt gebruikt gemaakt van internal objecten terwijl dit een hele effectieve manier is om duidelijk te maken welke code wel of juist niet aangeroepen mag worden.

Maar waarom zou ik private methodes niet mogen testen?
Een private methode is een implementatie detail van een object. Een test is bedoeld om het gedrag van mijn code te valideren en niet de implementatie details. Wanneer ik code refactor, dan wil ik dat de testen me waarschuwen wanneer ik onverhoopt een wijziging doorvoer in het gedrag van de code. Ik zit er niet op te wachten dat er testen omvallen omdat ik in de detail implementatie code aan het verbeteren ben. Het testen van private methodes, wat op zich al vraagt om kunst-en-vliegwerk, maakt je testen tightly coupled met de implementatie van je code en daarmee veel minder goed onderhoudbaar.

Hoe zit het dan met internal methodes?
Ik zei al eerder dat ik persoonlijk vind dat er te weinig gebruik wordt gemaakt in code van de internal access modifier. In mijn beleving zou dit eigenlijk de standaard moeten zijn, zodat je bewuster de keuze maakt om iets public te maken. Maar voor het testen van de integriteit van een object wil ik wel in staat zijn om ook internal objecten te testen. Anders ben je een kerstboom van onderliggende logica aan het testen. Binnen .NET is het vrij eenvoudig om je internals zichtbaar te maken voor een testproject, door gebruik te maken van de assembly attribute “InternalsVisibleTo”

private methoden niet opnemen in testen

Conclusie
Er zijn weinig onderwerpen waarover zoveel discussie online is als geautomatiseerd testen (op Agile werken na misschien 😊). Mijn voorkeur is het om heel bewust gebruik te maken van de access modifiers. Dit betekent dat iets internal is, tenzij het van buiten beschikbaar moet zijn, en dat ik alleen internal en public onderdelen opneem in testen. Ik ben benieuwd wat jullie in jullie team doen.