Ne, ganz sicher nicht - und mich wundert's, dass das hier nicht auch schon wieder zensiert wurde ...
Ab heute werden alle Threads automatisch geschlossen und müssen erst durch einem Moderator explizit geöffnet werden. Nach jeder neuen Antwort wird ein Thread automatisch sofort wieder geschlossen.
Um ehrlich zu sein - ich glaube, der Unterschied wäre in einigen Threads und bei einigen Moderatoren kaum spürbar ... SCNR
Was das ganze mit dem StackTrace zu tun hat, ist mir ehrlich gesagt auch nicht so ganz klar - wo ist da der Zusammenhang?
Ich würde mir irgendein Konzept im Detail erklären lassen - zum Beispiel die Garbage Collection: Was sind Generationen? Wann wird collected? Was ist ein Finalizer? Warum sollte man Finalizer - wenn möglich - vermeiden? Was ist die FReachable-Queue? Wie findet der GC die zu entfernenden Elemente?
Also einfach Dinge, von denen ich davon ausgehe, dass sie ein 08/15-Programmierer nicht kennt, aber die ich von einem wirklich guten Entwickler erwarten würde.
Außerdem würde ich ihm eine Aufgabe stellen, die ihn herausfordert, um zu sehen, wie er arbeitet. Das sagt IMHO mehr aus als das reine Wissen.
ZB: Schreibe eine Methode, die einen String umkehrt - ohne Schleifen zu verwenden, und ohne die String.Reverse-Methode zu verwenden. Und dann: Performance messen und optimieren. Kommt derjenige zB auf die Verwendung von Tail Recursion? Wie geht er mit der Aufgabe überhaupt um? Legt er direkt los? Plant er? Googlet er? ...?
Anscheinend nicht, sonst kämen ja nicht immer wieder verschiedene Nachfragen 😉.
Deine Aussage
Aber EBC 2.0 halte ich einfach für so krank, dass ich darin nicht den mindesten Aufwand investieren werde. Das ist für mich ein tot geborenes Kind. Ich habe es bisher vermieden, das so deutlich zu sagen. Aber dein Beitrag zwingt mich dazu, offen zu legen, warum ich mich in diesem konkreten Fall auf keine Diskussion einlasse. Jede Beschäftigung damit ist in meinen Augen verlorene Zeit.
Damit sollte jetzt wirklich alles klar sein.
hast Du (anscheinend nicht nur) für meinen Geschmack immer noch nicht begründet - was genau findest Du denn "so krank"?
Hallo "Kollege" 😉!
@ Arithmetik: Jups, kann mich da Peter nur anschließen. EBCs erfordern ein Umdenken in Richtung streambasierter Datenverarbeitung, aber hey, auch die OOP hat ein Umdenken erfordert. TDD ebenfalls. Funktionale Programmierung erfordert ein Umdenken. Na und?
EBCs haben diverse sehr deutliche Vorteile, der wichtigste aus meiner Sicht ist die extreme Entkopplung. Die Eignung für TDD & Co sind daraus eigentlich nur Folgen.
Aber wie Ralf ja schon angeboten hat: Wer Zweifel hat und ein ehrliches Interesse an einem Vergleich, ist herzlich zu einem "Shootout" eingeladen.
Hoi Jürgen,
(Wetten das dieser Beitrag gleich gelöscht ist? fg)
erstaunlich, es steht noch drin .... normalerweise hätte ich darauf nämlich auch gewettet 😉.
Übrigens kann ich mich Deiner Meinung nur anschließen:
@ herbivore: Ralf ist im Gegensatz zu Dir sachlich geblieben, und Formulierungen wie "krank" empfinde ich in diesem Zusammenhang als leicht "krank" ... Ralf kommt ja nun auch nicht daher und behauptet, mit den EBCs das Beste seit der Erfindung von geschnittenem Brot gefunden zu haben. Er hat ja nun schon mehrfach darauf hingewiesen, dass er an Erkenntnisgewinn und Erfahrungsaustausch interessiert ist.
Dass Du das so abblockst - schade. Zumal die Gründe zumindest für mich nicht wirklich nachvollziehbar sind (Argumente sehen für mich anders aus), mit "ich finde das krank" kann ich ja alles aushebeln und mich einer Diskussion entziehen.
Und was genau Du für ein Problem mit EBCs hast, wo Du die Nähe zur prozeduralen Programmierung siehst - das habe ich zumindest leider noch nicht verstanden, weil außer ein paar flapsigen Kommentaren keine wirkliche Antwort von Dir auf die Fragen kam.
Viele Grüße,
Golo
@NitramX:
Das ist aber vollkommen unnötig, denn rein Theoretisch kann zwischen der abfrage und dem löschen das Recht geändert sein.Akzeptiere einfach das bei Dateien fast immer der Weg des abfangens der jeweiligen Exception notwendig ist.
Es gibt keinen echten anderen Weg.
Genau darauf wollte ich hinaus 😃
An Hand welcher Kriterien würdest Du denn zuverlässig prüfen wollen, ob eine Datei gelöscht werden darf?
Der PC war doch eh noch nie DIE Spieleplattform schlechthin, es war immer die Plattform Nummer 2.
Die Nummer 1 waren:
Je komplexer Spiele werden, und je exakter die Steuerung sein muss, desto eher fand man die Spiele auf dem PC. Und das wird sich auch nicht ändern, da alle anderen Plattformen wesentlich beschränktere Eingabemöglichkeiten haben.
ABER: Der PC wird IMHO auch nie die Nr. 1 werden ...
Im Endeffekt brauchst Du so was wie einen Algorithmus, der Cluster findet, und dann für jedes Cluster prüfen, ob die Clustergröße passt oder nicht ...
Dafür bin ich zwar kein Experte, aber ich denke, das Stichwort "Cluster" sollte einige Anhaltspunkte bei Google erbringen 😉
100 Koordinaten, die in irgendeiner Fläche von x km² liegen?
oder
100 Koordinaten, die in einer bestimmten Fläche von x km² liegen?
Naiv gefragt: Wo liegt das Problem, in der Astaro-Software für Dich bzw Deine IP Zugriff auf die entsprechende Domain zuzulassen?
Wenn Du die Erlaubnis hast, wird es organisatorisch ja wohl kein Problem sein, und ich kenne die Astaro-Software nun nicht, kann mir aber kaum vorstellen, dass man so was nicht gezielt freigeben können sollte?
Auch ne einfache Variante: Schick Dir selbst E-Mails 😉
(ernst gemeint)
Falls das das gleiche ist wie bei F#: FULLACK
gibt es ein paar Empfehlungen, wie man sich als Newbie dem Thema Unit-Tests und TDD nähert (Literatur, Software)?
Was ich sehr empfehlen kann, ist das Buch "Pragmatic Unit Testing". Warum, wieso, weshalb - siehe Review von Pragmatic Unit Testing
Ich nutze keine automatisierte Variante - bei mir sind die Kommentare moderiert und Spam werfe ich halt per Hand raus.
Hallo sth_Weird!
FULLACK
Das ist das, was ich oben mit
Und was das ursprüngliche Beispiel angeht: Hier geht es um zwei Aktionen: Auslesen eines Wertes, und dann den Index erhöhen. Wenn das doch zwei Aktionen sind, warum sollte ich die krampfhaft in eine Zeile zusammenziehen? Das trägt IMHO ebenfalls nicht zur Lesbarkeit bei.
meinte.
Viele Grüße,
Golo
Ja, danke für die Aufklärung 😃
@ herbivore: Bekomm ich noch ne Antwort auf meine Fragen?
eine vollständige Einheitlichkeit der - ich nenne es mal Gestaltung - von Code wird es nie geben.
Und was genau wolltest Du uns damit jetzt sagen? Wofür oder wogegen ist das ein Argument? Bzw ein Beispiel?
Natürlich ist das nie vollständig gegeben - aber zumindest im Rahmen eines einzelnen Teams oder eines Projekts ist es durchaus erstrebenswert.
Es ist schon die große Frage, warum x++ so verbreitet ist, obwohl so gut wie alle Analogieüberlegungen für ++x sprechen.
Weil die Analogieüberlegungen in der Praxis in diesem Fall irrelevant sind. In den meisten Fällen (Schleifen zB oder obigem Beispiel) ist es nämlich egal, welche Variante genutzt wird.
Genauso wie die Frage, wie man es nun an sich macht, letztlich irrelevant ist. Die Codequalität wird dadurch nicht besser oder schlechter. Die Performance ist nicht besser oder schlechter. Per se ist auch nicht die Lesbarkeit besser oder schlechter.
Der Punkt ist einfach: Es hat sich halt so etabliert, vermutlich, weil die meisten Beispiele für Schleifen mit i++ und nicht mit i arbeiten, und weil C nun mal C++ heißt und nicht ++C, und dabei ist es dann einfach geblieben.
Natürlich kann man jetzt lang und breit argumentieren, warum, wieso, weshalb man das doch anders machen sollte - aber mal ganz ehrlich: Wozu?
Genauso gut könnte man darüber diskutieren, ob man bei einer Eigenschaft erst get und dann set oder erst set und dann get implementieren sollte. Das ist genauso egal. Fakt ist aber, es hat sich so eingebürgert, erst get, dann set - warum sollte man es da nun anders machen, auf die Gefahr hin, Missverständnisse drastisch zu erhöhen?
Hallo,
also ich muss mich da auch Peter anschließen - ich finde die Variante mit Postfix und in zwei Zeilen ebenfalls lesbarer.
Ist die Postfix-Schreibweise verbreiteter als die Präfix-Schreibweise. Postfix sind die meisten Entwickler gewohnt, Präfix nicht. Verwendet man nun Präfix, was ja durchaus einen semantischen Unterschied macht, läuft man Gefahr, dass die Lesbarkeit des Codes leidet. Insofern würde ich Präfix nicht einsetzen.
Und was das ursprüngliche Beispiel angeht: Hier geht es um zwei Aktionen: Auslesen eines Wertes, und dann den Index erhöhen. Wenn das doch zwei Aktionen sind, warum sollte ich die krampfhaft in eine Zeile zusammenziehen? Das trägt IMHO ebenfalls nicht zur Lesbarkeit bei.
Die Argumente für Präfix waren zwar viele, aber sonderlich überzeugend haben sie auf mich auch nicht gewirkt.
Viele Grüße,
Golo
Geht auch mit einer Extension-Method, die die zu Grunde liegende Liste verändert und ohne ToArray o.ä. auskommt:
using System;
using System.Collections.Generic;
namespace ListAdd
{
public class Program
{
public static void Main()
{
var list = new List<int>().AddItem(23).AddItem(42);
foreach(var item in list)
{
Console.WriteLine(item);
}
Console.ReadLine();
}
}
public static class ExtensionMethods
{
public static IList<T> AddItem<T>(this IList<T> source, T item)
{
source.Add(item);
return source;
}
}
}
Einziger Haken: Sie kann nicht Add heißen, weil der Compiler sie dann findet (IntelliSense interessanterweise allerdings schon 😉).
Hallo CSL,
der Lösung mit der Basisklasse würde ich den Vorzug geben, wobei die Basisklasse für meinen Geschmack noch abstract sein sollte.
Begründung Nr. 1: Die Basisklasse erfüllt keine "eigene" Funktionalität, es geht nur um das Auslagern von gemeinsamem Code. Insofern ist eine Basisklasse - zumal abstract - hierfür IMHO in diesem Fall die richtige Wahl.
Begründung Nr. 2: Helper-Klassen sind mir immer suspekt. Helper-Klassen haben oft so eine Aura der Art "Ich wusste nicht, wo ich das Zeug sonst hinpacken sollte".
Aber mal ganz abgesehen davon: Warum nicht per DI auflösen? Dann hättest Du das Problem gar nicht.
Viele Grüße,
Golo
Wie ich schon sagte: Mach, was Du willst.
EOD
Nein, das gleiche kannst Du mir nicht vorhalten, weil:
*ich mich seit rund einem dreiviertel Jahr intensiv mit Unittests und TDD beschäftige
*von Dir keine einzige relevante Quelle kam, die Deine Meinung bestätigt hätte
*ich beide Seiten aus eigener Erfahrung kenne, so wohl das Testen von privatem Code als auch der Verzicht darauf
*ich lernfähig bin, was TDD angeht, das habe ich öffentlich genug bewiesen, indem ich über meine eigenen Fehler und meine daraus gezogenen Lehren geschrieben habe
*ich mich vor 9 Monaten geäußert habe, dass Unittests und TDD vollkommen überbewertet seien, mir was anderes gesagt wurde, und ich mir das dann zu Herzen genommen habe
All diese Punkte fehlen bei Dir. Insbesondere den letzten vermisse ich.
So lange Du es nämlich nicht anders kennst und Du es nur von vornherein verurteilst, ist es schwierig, zu argumentieren - weil was will man gegen "Ich find das aber gut so" schon groß sagen?
Letztlich musst Du das nicht tun. Wie gesagt, wenn Du glücklich so bist, dann bleib dabei. Nur das dann als allgemeingültiges Gesetz der Form "Es spricht nichts dagegen, privaten Code per Reflection zu testen" zu erheben, wenn alle Welt was anderes sagt, das ist ein bisschen vermessen ...
Kannst Du ein URI-Schema als Adresse übergeben?
@ CSL:
Offensichtlich hast Du weder MVVM verstanden, noch hast Du das Problem mit der Reflection verstanden. Mit TDD hast Du Dich nach eigener Aussage noch nicht groß beschäftigt, und Unittests sind für Dich nach eigener Aussage noch relativ neu.
Man kann Dir zum Thema "privaten Code testet man nicht" als Quelle vorsetzen, was man will - Du siehst den Vorteil in den Accessoren als so überdramatisch wichtig an und ignorierst sämtliche Hinweise, dass an Deiner Testvorgehensweise etwas falsch sein könnte. So wie Du es beschreibst, hast Du auch nicht verstanden, wie das Testen in VS funktioniert bzw wie die Codecoverage arbeitet.
Da Du aber offensichtlich nicht gewillt bist, es Dir auch einfach mal anzugucken, und Deine bisherige Vorgehensweise für das Nonplusultra hältst, mit der Du sehr gute Architekturen baust und anscheinend ja perfekt getesteten Code entwickelst - was will man da noch sagen? Da fehlen mir irgendwann einfach die Worte.
Teste so, wie Du es für richtig hältst. Viel Erfolg damit.
@ CSL: Nein, ein TabControl gehört in die View. Weil es ein Control ist, das etwas anzeigt. Genauso gehören die Buttons zum Blättern in die View, weil sie die UI-Elemente darstellen.
Logik zum Weiterblättern ist nichts sichtbares und hat damit auch nichts in der View verloren, weil es eben keine UI, sondern UI-Logik ist. Deswegen gehört so was ins ViewModel.
Natürlich kannst Du es anders machen.
Es ging darum, für Dein konkretes Beispiel zu zeigen, dass es sehr wohl möglich ist, privaten Code so in eine andere Klasse als öffentlich zu verlagern, dass er gut testbar wird. Dass dem so ist, habe ich Dir mit MVVM gezeigt. Dass Du das nicht machen willst, ist Deine Sache, es ging ja aber darum zu zeigen, ob es denn überhaupt möglich wäre. Das habe ich gezeigt.
Du hast geschrieben, dass Du Dich mit Unittests noch nicht all zu lange befasst, und TDD für Dich noch relativ neu ist. Das ist okay, jeder fängt mal an. So lange ist es bei mir selbst ja auch noch nicht her.
Du siehst keine Vorteile im Nicht-Testen von privatem Code. Das ist okay, das ist Deine derzeitige Meinung. Du hast es aber - zumindest schien mir das so - auch noch nie wirklich anders versucht, bügelst es aber von vornherein als sinnlos ab, weil Du keine Vorteile siehst. Das finde ich schade. Denn manchmal erkennt man die Vorteile erst, wenn man es einmal eine Weile lang versucht hat.
Als Ergänzung: Ich habe zu dem Thema noch gebloggt, siehe http://www.des-eisbaeren-blog.de/post.aspx?id=fbf99245-0a81-46e7-bbab-3420cb8fe0d7
CSL, nein, es gehört nicht in die View, sondern ins ViewModel. Genau dafür gibt es dieses nämlich. Siehe MVVM-Pattern.
Und wieso die darin enthaltenen privaten Methoden nicht im ViewModel öffentlich gemacht werden können, habe ich nach wie vor nicht verstanden.
Wegen dem VS CodeCoverage wurde Dir bereits von dN!3L geantwortet:
Dann musst du entweder mehr Tests schreiben (mit Parametern, sodass alles getroffen wird), oder aber deine privaten Methoden enthalten wirklich Code, der nie benutzt wird.
Du musst dir erstmal genauer Gedanken machen, warum du wirklich nicht auf 100% kommst bzw. kommen kannst. Und dass die Unittest-Methode die einzige ist, die den Code mal durchläuft (nur damit eine dir wichtige Zahl größer wird), kann auch auch nicht Sinn und Zweck sein...
Weißt Du, was mich etwas wundert? dN!3L hat Dir gesagt, dass es Quatsch ist. Ich habe Dir gesagt, dass es Quatsch ist. FZelle hat gesagt, dass es Quatsch ist. Bei StackOverflow sagen eine Menge Leute, dass es Quatsch ist. Bei Wikipedia steht, dass es Quatsch ist.
Dass Du es anders siehst, ist Dein gutes Recht. Aber was mich wundert, ist, dass es Dich nicht zumindest einmal nachdenklich stimmt, wenn nicht nur hier im Forum gesagt wird, dass man privates nicht testet.
Um es mal auf den Punkt zu bringen: Hast Du es schon einmal getestet mit privates in eigene Klassen auslagern ausprobiert? Und damit meine ich nicht nur mal eben fünf Zeilen hin- und hergeschoben, sondern mal ein etwas größeres Beispiel auf die Art entwickelt?
Und PS: Es wird weder genauer getestet noch validiert, wenn Du private-Code testest. Wenn Deine Tests im public-Fall schlechter sind, heißt das, dass Dein Code nicht sauber strukturiert ist.
Deine View soll Daten anzeigen. Nicht mehr und nicht weniger. Das ist der Sinn einer View. Wie der Name schon sagt 😉. Sie hat nicht als Aufgabe, vor oder zurück zu blättern, oder sonstwas zu machen. Sie hat nur ein paar Buttons, mit denen man das Vor- und Zurückblättern auslösen kann.
Wenn Deine View mehr macht, als nur anzeigen und Eingabefelder bieten, verletzt sie das SRP. Darüber brauchen wir nicht diskutieren, das ist so.
Wenn es nun nicht möglich ist, das Blättern zu testen, weil das Blättern irgendwie privat in der View drin steckt, macht die View mehr als sie soll, und erfüllt für meine Begriffe den Term "unsauber". Sie zeigt nicht nur an.
Wenn Du irgendwann (hypothetisch) doch eine andere View einführen müsstest, hättest Du ein Problem. Daran siehst Du, dass die Trennung nicht sauber ist. Ob Du diese View jemals brauchen wirst oder nicht, ändert ja nichts an der Tatsache, dass View und Logik nicht sauber getrennt sind.
Kurzum: Zumindest in Bezug auf die View kann ich nach Deiner kurzen Darstellung nicht erkennen, dass die View eine sehr gute Architektur aufweist. Vielleicht tu ich Dir damit unrecht - ich kenne den Code ja auch nicht. Was Du beschreibst, klingt aber alles andere als sauber.
Und wie ich schon sagte: Es geht nicht um nicht können, sondern um nicht wollen - denn wenn Du wolltest, könntest Du die Trennung ja herstellen. Es ist Dir aber zu viel Aufwand. Das mag berechtigt sein. Es ist aber kein berechtigter Grund für die Aussage, dass es nicht ginge - denn das tut es sehr wohl.
Das ist aber dann Dein Problem. Dein Code ist nicht sauber getrennt, weil die View mit dem Model stärker zusammenhängt als notwendig. Es steht Dir ja frei, ein Interface einzuführen und Dein Testproblem damit zu lösen.
Die Argumentation, dass es nicht anders möglich wäre, hast Du damit gerade ad absurdum geführt.
Es geht in diesem konkreten Fall nämlich nicht um nicht können, sondern um nicht wollen.
1.Nein, meine Klassen haben private Methoden. Die sind aber über die aufrufenden öffentlichen Methoden mit abgedeckt. 1.Wieso wird in Deinem Beispiel niemals die MoveCurrent-Methode über die öffentliche Schnittstelle aufgerufen?
Sauber wäre doch, wenn Du hinter der Form ein Modell hast, das den aktuellen Stand repräsentiert (quasi ein ViewModel 😉), das zwei Methoden bietet: MoveNext, MovePrevious.
Die sind öffentlich und werden von der Form aufgerufen.
Und dann wird auch MoveCurrent von MoveNext und MovePrevious aufgerufen. Wenn Du die beiden richtig testest, wird MoveCurrent ja automatisch mitgetestet.
Wo ist da das Problem?
Nun, ich schreibe eine Komponente, die einen HTTP-Stream zusammenbauen soll - unabhängig vom IIS beziehungsweise von ASP.NET, um diese Komponente auch unabhängig vom IIS / ASP.NET testen zu können.
Nur wäre es halt schön, diesen HTTP-Stream nicht per Hand zusammenfummeln zu müssen.
Auch der umgekehrte Weg, einen HTTP-Stream in einen HttpResponseStream umzuwandeln, wäre interessant.
Contra:
*Refactoring komplizierter
*Abhängigkeit von Interna, die mich als Außenstehender nichts angehen (ein Test ist wie jeder andere Verwender auch ein solcher Außenstehender)
*Tests sind ein Verwender von Code => jeden anderen Verwender interessiert auch nur der Kontrakt, nicht das Innenleben
Umgekehrt möchte ich Dich fragen:
Welche Nachteile siehst Du, wenn man die privaten Methoden in öffentliche umwandelt und in neue Klassen mit dedizierter Aufgabenstellung gemäß dem SRP verpackt?
PPS: Wikipedia schreibt unter http://de.wikipedia.org/wiki/Modultest#Eigenschaften_von_Modultests:
Test des Vertrages und nicht der Algorithmen
Modultests sollen gemäß dem Design by contract Prinzip möglichst nicht die Interna einer Methode testen, sondern nur ihre externen Auswirkungen (Rückgabewerte, Ausgaben, Zustandsänderungen, Zusicherungen). Werden auch interne Details der Methode geprüft (dies wird als White-Box-Testing bezeichnet), droht der Test fragil zu werden, er könnte auch fehlschlagen, obwohl sich die externen Auswirkungen nicht geändert haben. Daher wird in der Regel das sogenannte Black-Box-Testing empfohlen, bei dem man sich auf das Prüfen der externen Auswirkungen beschränkt.
PS: Noch mal zum Thema "allgemeingültig" ...
Google-Suche nach "what to unittest public private" liefert als zweiten Treffer einen interessanten Treffer von stackoverflow.com.
Am besten geratete Antwort (mit 49 Ups):
If you want to unit test a private method, something may be wrong. Unit tests are (generally speaking) meant to test the interface of a class, meaning its public (and protected) methods. You can of course "hack" a solution to this (even if just by making the methods public), but you may also want to consider:
If the method you'd like to test is really worth testing, it may be worth to move it into its own class.
Add more tests to the public methods that call the private method, testing the private method's functionality. (As the commentators indicated, you should only do this if these private methods's functionality is really a part in with the public interface. If they actually perform functions that are hidden from the user (i.e. the unit test), this is probably bad).
Die zweitbeste Antwort (mit 15 Ups) bezieht sich auf InternalsVisibleTo.
Quelle: http://stackoverflow.com/questions/250692/how-do-you-unit-test-private-methods
Ich bin deshalb nicht darauf eingegangen, weil für mich die Nachteile die Vorteile um Welten überwiegen.
Was das Testen von privatem Code angeht: Entweder liefern mir die Methoden, Eigenschaften, Events, ... die als public im Kontrakt definiert sind, das zurück, was ich erwarte, oder nicht. Ob der Fehler dann aus dem public-Element direkt stammt oder aus einem dahinterliegenden private-Element sehe ich nicht auf Anhieb. Das stimmt. Nur findet man das im Normalfall relativ fix über den Debugger raus, indem man durchsteppt.
Wenn in privaten Methoden dermaßen viel Code ist, dass jetzt als Gegenargument kommt, dass das zu viel Aufwand wäre, dann kann ich mich nur wiederholen: Dann steckt in der privaten Methode zu viel Logik, die in 99% der Fälle ausgelagert gehört.
Sorry, herbivore, Du hast => DEINE ≤ Sicht beschrieben, warum. Die ist doch nicht allgemein gültig?
sicher war das zu dem Zeitpunkt, als ich es geschrieben hatte, nur meine Sichtweise darüber, wie SeboStones Beitrag gemeint war. Aber nachdem SeboStones mittlerweile bestätigt hat, dass er tatsächlich so gemeint war, ist es die allgemeingültige Sichtweise. Oder wie SeboStones es formuliert hat:Herbivore hat mich richtig verstanden, Golo und FZelle leider nicht.
Nein, herbivore - es ist Deine und SeboStones Sichtweise. Nicht die allgemeingültige. Wenn es sie wäre, würde hier nicht so viel Gegenwind kommen, siehe FZelle, dN!3L und ich. Und wir alle drei nicht gerade erst seit gestern entwickeln, empfinde ich es als etwas überheblich, wenn Du Deine beziehungsweise Eure Meinung als "allgemeingültig" darstellst und unsere Meinung mit einem Handschlag wegwischst.
..., als ob FZelle ein Fanatiker wäre, der seine (in Deinen Augen) falsche Meinung auf Biegen und Brechen durchboxen muss.
Richtig, genau das war in diesem konkreten Fall mein Eindruck.
Ich muss mir wirklich Mühe geben, hier nicht sarkastisch zu werden - aber etwas Reflektion wäre in diesem Fall gegebenenfalls nicht verkehrt.
Genau das, was dN!3L beschrieben hat, meinte ich: Man ziehe das Ding in eine eigene Klasse und mache es public.
1.Haben dann alle was davon (gegebenefalls muss man es ein wenig generischer machen, aber prinzipiell ist die Idee ja gemeingültig).
1.Kann man es dann problemlos testen, weil public.
1.Erschließt sich mir immer noch nicht, warum dieser Code in einer Klasse, die eigentlich eine ganz andere Aufgabe erfüllt, als private Methode herumliegen sollte.
Zum Thema, wie man privaten Krams testet. Dazu gibt's in meinen Augen nur eine Handvoll Varianten, die aber alle ihre Nachteile haben und für mich persönlich deshalb nicht in Frage kommen:
1.Per Reflection. Nachteil: Abhängigkeit von Magic Strings, keine Unterstützung bei Refaktorisierung.
@ CSL: Dazu zählt auch der Accessor. IMHO eine ganz schlechte Idee, das so zu machen. Um ehrlich zu sein: Von den hier aufgezählten vier Möglichkeiten ist es die in meinen Augen schlechteste.
1.private in protected umwandeln und Test ableiten: private und protected sind zwei Paar Schuhe und haben nicht die gleiche Semantik. Zudem keine Unterstützung bei sealed Klassen. 1.private in internal umwandeln und InternalsVisibleTo nutzen: Auch hier, andere Semantik von private und internal. 1.Zustand als Abhängigkeit (siehe http://ralfw.blogspot.com/2009/11/zustand-als-abhangigkeit-ioc-konsequent.html): Für mich von allem noch die sauberste Lösung, weil die wenigsten Probleme bestehen. Trotzdem Nachteil: Zusätzlicher Konstruktor notwendig, es wird nicht der Konstruktor verwendet und getestet, der auch im Produktivcode zum Einsatz kommt.
Alles in allem gibt es für mich keinen sauberen Weg, privaten Code zu testen.
Aber: Ganz abgesehen davon kann ich nur FZelle beipflichten, der weiter oben bereits erklärt hat, warum man privaten>Code nicht testet: Weil er Interna betrifft und nicht den nach außen zugesicherten Kontrakt.
Okay, dann liegt's an folgendem:
Ein Dictionary ist ja nichts anderes als eine Hashtable - Keys werden Werte zugeordnet.
Und es macht einen Unterschied in der Hashberechnung wegen der Kollisionen (meine ich), ob die Länge der Hashtabelle eine Primzahl ist oder nicht. Siehe zum Beispiel: http://srinvis.blogspot.com/2006/07/hash-table-lengths-and-prime-numbers.html
Hat irgendwas mit dem chinesischen Restsatz zu tun, IIRC - aber das Studium ist lange her 😉.
Nur damit ich es richtig verstanden habe:
Angenommen, die Liste ist mit 16 Einträgen voll, dann wird geguckt, was die doppelte Größe ist (32), und dann die darauffolgende nächste Primzahl gesucht (das wäre die 37), und diese dann herangezogen als neue Größe?
Hallo,
folgende Aufgabe: Es soll ein HTTP-Request / -Response zusammengebaut werden. Das Ergebnis soll als string / Stream vorliegen.
Prinzipiell ist das ja kein Problem. High-Level geht das in ASP.NET mit den Methoden auf HttpResponseStream, Low-Level geht es, indem man den Stream / string per Hand zusammenbaut.
Was ich nun suche, ist so eine Art Mittelweg. Wo ich quasi ein HttpStream-Objekt erzeuge, dort Methoden wie AddHeader, SetMimeType und ähnliches habe, und nachher sagen kann, gib mir das ganze bitte als Stream oder string zurück. Bei ASP.NET habe ich im OutputStream zum Beispiel nur den Content stehen, nicht jedoch die Header.
Kennt jemand eine Komponente, die so etwas leisten kann?
Viele Grüße,
Golo
schließlich wird es ja auch nur für die Tests erstellt und ist Hilfslogik für die Tests.
nein, das stimmt beides nicht. Ich habe schon beschrieben warum.
Sorry, herbivore, Du hast => DEINE ≤ Sicht beschrieben, warum. Die ist doch nicht allgemein gültig?
Und gleich von verrannt zu sprechen, halte ich für etwas ... Fehl am Platze, um es mal vorsichtig auszudrücken.
Das bezog sich gar nicht auf das Missverständnis, sondern auf den in meinen Augen verzweifelten Versuch von FZelle, die Absolutheit der Regel, dass nur öffentliche Methoden getestet werden dürfen, trotz plausibler Gegenbeispiele aufrechtzuerhalten.
Mich hat hauptsächlich die Formulierung "verrannt" gewundert. Das klingt so ... absolutistisch, als ob FZelle ein Fanatiker wäre, der seine (in Deinen Augen) falsche Meinung auf Biegen und Brechen durchboxen muss. Das Wort "verzweifelt" geht in die gleiche Richtung.
Wie gesagt, mich wundern die Formulierungen ein wenig ...
Im Übrigen: Ich halte es nach wie vor für Blödsinn, privaten Code zu testen. Aus verschiedenen Gründen. Die genannten Beispiele (wieso eigentlich Beispiele? Es war doch nur eins?) haben mich nicht wirklich überzeugt.
Du hast selbst doch geschrieben, dass diese Helper-Klasse allgemein sein könnte:
Im Prinzip wird hier ein Aspekt, nämlich das an verschiedenen Stellen immer gleich Exeption-Handling, ausgelagert. Das reduziert die Redundanz der Modellklasse. Den ExceptionCatcher wäre also auch dann sinnvoll, wenn man überhaupt keine Unit-Tests schreiben würden.
Einen besseren "Beweis" als diesen kann es doch kaum geben, dass es eben nicht private zu sein hat - eben WEIL es an noch mehr Stellen Sinn machen würde.
herbivore,
ich muss an dieser Stelle FZelle zur Seite stehen - ich sehe das genauso wie er. AUch für mich ist das keine Businesslogik, und gehört zu den Tests - schließlich wird es ja auch nur für die Tests erstellt und ist Hilfslogik für die Tests.
Und woher Du weißt, ob etwas missverstanden wurde, ist mit schleierhaft - ich denke, das kann nur SeboStone beantworten.
Und gleich von verrannt zu sprechen, halte ich für etwas ... Fehl am Platze, um es mal vorsichtig auszudrücken.
Viele Grüße,
Golo
Die Frage ist doch, ob das Überprüfen der Qualität überhaupt in die Klasse gehört, die den Kaffee kocht - oder ob das nicht als public-Methode in eine eigene Kaffee-Qualitäts-Tester-Klasse gehört.
Aus meiner Erfahrung deutet der Bedarf, privates zu testen, meistens darauf hin, dass Komponenten noch nicht fein granular genug sind.
A propos Buch:
Als Empfehlung: Review von Pragmatic Unit Testing
"Nicht genug geplant" wäre jetzt auch meine Antwort gewesen.
Ein "Fehler" ist in meinen Augen auch, privates zu testen - es ist für den Unittest total egal, wie Du das intern aufziehst: Alles in einer Methode direkt, oder mit fünf privaten Methoden. Getestet wird nur die öffentliche Schnittstelle.
Denn nur die ist es, die den Verwender interessiert. Die Implementierung ist eine Blackbox.
Und was das Refactoring angeht, wenn eine Methode "zu viel" macht: Auch hier entweder wieder zu wenig geplant, oder - wenn Du nach TDD vorgehst - merkst Du ja schon beim Test schreiben, dass es sich irgendwie seltsam anfühlt, und kannst direkt gegensteuern.