Rolf b: Falsche Parametertypen

Beitrag lesen

Hallo,

mit den Unit Tests bei eigenem Code meinte ich folgendes: Wenn ich ein Programm schreibe, dann erzeuge ich Unit-Tests für alle öffentlichen Schnittstellen der von mir erstellten Klassen (bzw Funktionen) und befeuere sie so mit Testdaten. Wenn mein Programmcode korrekt ist, wird es bei den daraus folgenden internen Aufrufen nicht zu Typfehlern kommen. Wenn doch, ist zu erwarten, dass der Unit-Test fehlschlägt.

Wenn ich Unit-Tests für eine Klasse schreibe, die Abhängigkeiten zu einer anderen Klasse hat, dann mocke ich diese Abhängigkeit und prüfe im Unit-Test, ob meine Mocks wie erwartet aufgerufen wurden. Wenn die getestete Klasse falsche Typen übergibt, merke ich das an dieser Stelle. Seinen Code so zu schreiben, dass das überhaupt möglich ist, ist die hohe Kunst des TDD.

Solange die zuvor erwähnten Klassen und Funktionen so aufgerufen werden, dass ich die Kontrolle über den Aufruf habe (sprich: der Aufruf durch meinen eigenen Code erfolgt), brauche ich keine Typvalidierung. Denn ich unit-teste ja meinen eigenen Code und weiß, dass er keine falschen Typen ausspuckt. Falsche Wertebereiche vielleicht schon, ggf. sind dagegen Prüfungen erforderlich. Das ist eine Designfrage und nicht allgemein zu beantworten.

Funktionen, die ihre Aufrufparameter auf Typrichtigkeit prüfen müssen, sind solche, die von Stellen aufgerufen werden können, die nicht meiner Kontrolle unterliegen. Also dann, wenn ich von irgendwoher ein JSON Objekt vor die Füße gekübelt bekomme. Oder wenn ich nicht das Hauptprogramm schreibe, sondern eine allgemeine Bibliothek veröffentlichen will wie jQuery, Knockout oder Angular. Zumindest muss ich dann eine Debug-Version bereitstellen, die direkt beim Einstieg in eine öffentliche Schnittstelle genauer prüft und dem Entwickler während der Testphase direkt beim Aufruf "Du Depp" sagt, statt mit den unbrauchbaren Daten weiterzumachen, sie über 17 Stufen weiterzureichen, vielleicht sogar 3x in Closures zu verpacken und sich drei Mausklicks später unvermittelt darüber zu erbrechen. Oder schlimmer noch, den Code im Bunker auszuführen (try-catch, der Exceptions verwirft) und den Nutzer raten lassen, woher in der finsteren Höhle das urk kommt.

Wenn die Prüfungen dazu führen, dass der Code zu langsam wird, kann man immer noch eine Release-Version mit reduzierten Prüfungen bereitstellen.

Dein Hinweis zu primitiven und gewrappten Typen ist durchaus interessant. Du hast recht, dass man die bei einer Typprüfung nicht über einen Kamm scheren kann. Aber Du kannst Dir bei Number zumindest damit das Leben erleichtern, dass Du Number als Funktion nutzt. Number(3) (ohne new!) ergibt die primitive 3. Number("3") ergibt AUCH die primitive 3. Number(" 3") ebenfalls. Auch Number(new Number(3)). Number("3a") ergibt dagegen NaN.

Ein weiterer Grund für Typprüfungen sind Funktionen, die so tun als wären sie überladen. Die schauen sich ihre Parameter an, um herauszufinden, welche Aufrufvariante der Nutzer wohl gemeint haben könnte (jQuery ist ein prima Beispiel für Spekulatius dieser Art). Aber das ist wohl nicht das, wonach Du gefragt hast.

Zu dedlfixens Irr-Elefant: Ich habe ja nur versucht, einen Grund zu finden, warum man an der Stelle eine Präferenz für === haben könnte. Ob bei einem Typvergleich "==" oder "===" verständlicher ist, tja, keine Ahnung. Ich WEISS, dass ich auf beiden Seiten strings haben werde. Insofern ist's semantisch an dieser Stelle Wurscht und nur die hauchzarte Wurstpelle der Performance blieb für mich als Grund übrig.

Rolf