Weet je zeker dat je MOQ nog wilt gebruiken? Vreemde actie van de auteur van de code.

Ingediend door Dirk Hornstra op 04-sep-2023 20:54

Credits voor deze bevinding aan mijn TRES-collega Johannes Braaksma. Hij deelde met ons 2 artikelen, namelijk het issue in Github van Sponsorlink: link en de Youtube-video van Nick Chapsas: link.

Waar komt het in het kort op neer?

Veel code die je maakt is afhankelijk van "externe" zaken. Er wordt een map gescand op bestanden, er wordt informatie uitgewisseld met een externe API, er worden gegevens opgehaald uit een database en de aangepaste gegevens daarin opgeslagen. Dat zorgt ervoor dat als je jouw code wilt testen en die zaken worden "geraakt", je moet zorgen dat het werkt. Veel bedrijven hebben naast een productie-omgeving van hun API ook een test-omgeving die je kunt gebruiken. In je project hebt je een code-first database-model gemaakt, zodat je makkelijk op je eigen pc een werkende database aan kunt maken, mogelijk in een Docker container. Maar het komt ook voor dat leveranciers "alleen maar" een productie API beschikbaar hebben. En je wilt daar natuurlijk geen testorders naartoe sturen, want als je /api/OrderRolex aanroept en je moet die Rolex ook nog zelf betalen, dan wordt het een dure test. Voor jou!

Nu kun je zelf allemaal zaken gaan bouwen, je maakt een Interface die binnen komt en voor je test gebruik je een andere Class dan de "echte Class"  die in productie gebruikt wordt. Ook een beetje de standaard procedure als je in .NET Core werkt, want dat is de basis van dependency-injection. Je geeft aan dat er een bepaalde interface binnen komt en bij het deel waar de applicatie start geef je van welke implementatie daarvoor gebruikt wordt.

Maar goed, budgetten en tijd zijn altijd "krap" en het is natuurlijk ook niet zo slim om zelf een hele implementatie te bouwen van bepaalde objecten, alleen maar omdat je wilt kunnen testen. En gelukkig zijn er dan bepaalde Frameworks die je in je code kunt toevoegen en die dat werk voor jou doen. Moq is één van de bekendste frameworks.

Het grootste deel van de developers gebruikt voor het bouwen van hun .NET projecten Visual Studio ( en sommigen Rider van JetBrains ). En Visual Studio Code kan ook steeds beter hiervoor gebruikt worden. In Visual Studio is een grote plaats voor "nuget-packages" ingericht. Dat zijn externe code-bibliotheken die je kunt toevoegen aan je project. Deed je vroeger wat met JSON, dan voegde je altijd NewtonSoft.Json toe, daarmee had je objecten en functies die met JSON konden omgaan en alles voor je regelden. Inmiddels heb je dat niet meer nodig en kun je System.Text.Json van Microsoft zelf gebruiken. Maar ook onderdelen van het .NET Framework biedt Microsoft zelf aan via nuget-packages, omdat het een mooi kanaal is om updates te verspreiden: is er een foutje gefixt, zijn er nieuwe features toegevoegd: update je nuget-packages en gaan met die banaan! Het is zelfs zo dat in Azure Devops en (Github vermoed ik?) je Dependabot kunt toevoegen, deze tool maakt automatisch PR (Pull Requests) aan als er een nieuwe versie van een nuget-package beschikbaar is. Die je nog wel zelf moet controleren en kunt mergen. Of verwijderen als je het niet wilt. Maar ik vermoed dat je ook de mogelijkheid hebt om met acties of andere plugins te zorgen dat zo'n PR automatisch gemerged wordt en doorgezet wordt naar bijvoorbeeld een test-omgeving, zodat daar gevalideerd kan worden of er niets kapot gaat door de update.

Een update kan niet alleen code bevatten om fouten te herstellen, om nieuwe zaken toe te voegen, maar ook om bepaalde onderdelen te laten vervallen. En als die code in je project aangeroepen wordt, dan kan je project niet meer gebouwd worden. En moet een developer gaan kijken wat de nieuwe functie hiervoor is, hoe die aangeroepen moet worden en of die nog doet wat de oude functie deed. Dus mocht jouw leverancier je een factuur sturen omdat "code up-to-date gehouden wordt", dan is dat in de meeste gevallen de achterliggende reden. Zo had je vroeger bijvoorbeeld dat AutoMapper (een bibliotheek die ervoor zorgt dat gegevens uit een database gekoppeld werden aan objecten in de code) automatisch bepaalde zaken die niet expliciet gekoppeld waren, maar qua naam overeen kwamen gekoppeld werden. Dus je code werkte prima. Tot in een latere versie juist die koppeling expliciet gemaakt moet worden. Ook wel weer logisch, want er zullen waarschijnlijk situaties geweest zijn waarbij dit ongewenste situaties opleverde, maar voor onze code was het vervelend, want nu moesten voor tig tabellen met tig velden al die koppelingen in code toegevoegd worden.

Tot zover de basis over code, het test-framework Moq en nuget-packages.

Uit de Youtube-video, het blog-artikel en de thread op Reddit maak ik op dat de auteur van Moq wat extra inkomsten wil voor zijn onbetaalde werk. Op zich geen verkeerd idee, maar de uitwerking is redelijk desastreus. Vanaf versie 4.20 komt er een stuk closed-source mee met Moq, wat een scan doet op je e-mailadres en doorstuurt naar een website. Daar wordt gevalideerd of je een sponsor bent. Zo ja, dan krijg je een bedankje, zo nee, dan krijg je een warning in je Build-output. Naast het feit dat er niet om goedkeuring gevraagd wordt om je e-mailadres te delen, vraag ik me af of dat proces ook blijft "hangen" als ik op een pc zonder internetverbinding zit. En sowieso wat dat aan extra wachttijd toevoegt op mijn trage ADSL-connectie ;) , ik wil gewoon builden, niet dat één of ander proces nog extra dingen doet. En dan het feit dat je een warning toevoegt in de Build-output, allemachtig! Een build van code is bedoeld om een applicatie te bouwen, niet om een soort chat met developers van code-bibliotheken op te bouwen. Want als iedereen dat straks gaat doen, in een niet al te groot project kun je al gauw 20 of meer nuget-packages gekoppeld hebben. En als die straks allemaal "de groetjes aan jou en je familie" gaan doen, dat is het moment dat ik maar weer in Notepad moet gaan programmeren.

Als je geld wilt verdienen, dan moet je de ontwikkeling aan moq op een lager pitje zetten en een commerciële variant op de markt zetten. Die misschien gebaseerd is op moq, maar "extra dingen" kan. Zaken die misschien de gemiddelde gebruiker niet nodig heeft, maar waar anderen wel behoefte aan hebben en ook in die mate dat ze daarvoor willen betalen. Of je ontwikkelt door aan het project en levert bepaalde zaken wel op, maar mensen die je sponsoren, die krijgen deze via een alternatieve manier aangeleverd. Je kunt redelijk simpel zelf een nuget-repository hosten. Als je daar nu de code aanbiedt die je in je publieke repo over 3 maanden beschikbaar maakt, dan heb je een soort premie-model wat volgens mij wel acceptabel is.

De wijziging is inmiddels ongedaan gemaakt (waarschijnlijk door de storm van kritiek die losgebarsten is), zoals mijn collega Jeroen Jonkman constateerde.

De actie die de auteur nu uitgevoerd heeft is onacceptabel. Als "goed developer" probeer je jouw nuget-packages in je projecten up-to-date te houden, vooral omdat er mogelijke security-zaken mee gefixt worden. Maar hiermee haal je mogelijk het paard van Troje met je goeie gedrag binnen! Nu er een rollback uitgevoerd is, is de noodzaak om over te stappen minder groot. Maar mocht je het willen doen, Nick heeft het in zijn Youtube-video over het alternatief NSubstitute ( hier te vinden ), zijn er nog andere kandidaten?

 

Nog een niet-relevante toevoeging, dit is ook de reden dat ik altijd moet lachen om die advertenties waarin gezocht wordt naar een "full-stack developer". Daarbij wordt verwacht dat degene die reageert thuis is in front-end development én back-end development. Ik las recent de tekst van een vacature waarbij de persoon ook nog leiding moet kunnen geven aan een team, de stand-ups en ook de demo's worden door deze persoon uitgevoerd. Die persoon hoeft nog net niet de toiletten schoon te maken (of dat wordt nog besproken bij het intake-gesprek), maar het is wel duidelijk: je moet zo'n beetje alles doen. En dat is gewoon niet te doen. Software, tools, frameworks, het is altijd in beweging. Bij front-end hoef je niet meer aan te komen met jQuery, Knockout JS is alweer passé, dus als je daar bij wilt blijven moet je volgens mij veel blogs en andere zaken volgen. Hetzelfde geldt voor back-end zaken. Met classic ASP hoef je nu niet zoveel meer te doen, de kennis van Pascal die je gebruikte in Delphi, daar ligt een dikke laag stof overheen. De .NET Core versies van Microsoft worden steeds verder ontwikkeld, hetzelfde geldt voor C#. En je moet in de gaten blijven houden welke security-zaken spelen en mogelijk jouw software kunnen raken. En dat moet je liefst zo snel mogelijk fixen. Dankzij Johannes ben ik nu op de hoogte, maar anders had ik het waarschijnlijk niet geweten. In een aantal projecten wordt moq gebruikt, dat het nog niet bijgewerkt is komt omdat het in projecten waaraan de laatste tijd niets gewijzigd is (en je dus ook niets hoefde te testen). Was dat wel zo geweest, dan hadden we waarschijnlijk wel de updates doorgevoerd, want dat is hoe het hoort. Toch? En dan heb ik het nog niet eens over het volgen van cursussen of zelfstudie om certificaten te halen. Daar gaat ook altijd veel tijd in zitten. En dat is eigen tijd: in de avonduren. En dan heb je ook nog certificeringen waarbij je die na verloop van tijd weer moet verlengen (dus eerst weer in de boeken, weer een examen doen) om gecertificeerd te blijven. So much to do in so little time...