OOP Testen - JUnit

Status
Nicht offen für weitere Antworten.

beginner99

Aktives Mitglied
Hallo,

ich bin ein wenig unschlüssig oder unsicher wie die Testmethoden aussehen sollten. Um das zu erläutern, hier ein kleines Bsp.:

Ich habe eine Klasse, die die settings der "Applikation"(was ganz simples, bin am lernen) beim start einlesen tut und beim beenden in das File zurückschreibt.

Um die Lese-methode zu testen, muss ich jetzt aber zuerst ein File schreiben und um die Schreib-Methode zu testen, muss ich es anschliessend lesen, um zu sehen, dass auch das richtige geschrieben wird.

Es wäre als somit am besten diese beiden Methoden in einem einzigen test zu testen?
-> zuerst X schreiben und dann schauen ob beim lesen wieder X ausgegeben wird

Oder sollten die Methoden einzel getestet werden? (dann hängt aber der Lese-Test trotzdem vom erfolg der Schreib methode ab).
 

manuche

Bekanntes Mitglied
Also du hast recht, du kannst sowas nur testen, indem du erst schreibst und dann liest und vergleichst! Ist in dem Fall ein Deadlock! Auch wenn die Schreibmethode funktioniert, heisst das ja noch lange nicht, dass es auch die Lesemethodetut! Also kann die Schreibmethode richtig sein aber der Test läuft schief... Verzwickt...
Erzeuge dir also erst eine Beispieldatei und prüfe in JUnit auf einen richtig statisch einprogrammierten Text der in der Datei steht! Wenn das passt kannst du das Schreiben testen!

Zweifle nicht an der vorgehensweise von JUnit... Nimm es hin und lass es danach links liegen!
Ich musste es für die Schule lernen und hab mich die ganze Zeit gefragt, ob es nicht unsinnig ist... Meine Klasse kam auf jeden Fall einstimmig zum Ergebnis "Ja, es ist unsinnig"!
Wir haben es also alle brav für die nächste Klausur so hingenommen wie es war. JUnit ist extrem fern von der Praxis wie ich finde!
 

tfa

Top Contributor
Ich habe vor kurzem auch Tests für eine User-Settings-Klasse geschrieben. Laden und Speichern werden in unabhängigen Methoden getestet. Dateien muss man dabei nicht anlegen. Die Testdaten kannst du z.B. über einen InputStream lesen bzw. in einen OutputStream speichern. Im Test leitest du diese Streams in StringBuffer um, so kannst du Testdaten für das Lesen liefern und die von der Settingsklasse geschriebenen Daten überprüfen.

Zweifle nicht an der vorgehensweise von JUnit
Guter Ratschlag.

Nimm es hin und lass es danach links liegen!
Schlechter Rat. Verstehe es und setze es ein!

Ich musste es für die Schule lernen und hab mich die ganze Zeit gefragt, ob es nicht unsinnig ist... Meine Klasse kam auf jeden Fall einstimmig zum Ergebnis "Ja, es ist unsinnig"!
Wir haben es also alle brav für die nächste Klausur so hingenommen wie es war. JUnit ist extrem fern von der Praxis wie ich finde!
Also ich setze Unit-Tests ein und finde es sehr hilfreich und wichtig. Mittlerweile ist man sich in der Praxis darüber glaube ich einig.
Was findest du denn unsinnig? Es ist vielleicht ein wenig lästig und macht weniger Spaß als einfach nur rumfrickeln. Aber spätestens wenn das, was man macht, auch funktionieren soll, sollte man Tests nicht links liegen lassen.
 
B

bygones

Gast
Zweifle nicht an der vorgehensweise von JUnit... Nimm es hin und lass es danach links liegen!
[...]
Ich musste es für die Schule lernen und hab mich die ganze Zeit gefragt, ob es nicht unsinnig ist... Meine Klasse kam
auf jeden Fall einstimmig zum Ergebnis "Ja, es ist unsinnig"!
[...]
JUnit ist extrem fern von der Praxis wie ich finde!
um es mal in heutiger Sprache auszudruecken:

EPIC FAIL


Testing ist in moderner Softwareentwicklung unabdingbar und eins der wichtigsten Elemente. Es nicht zu nutzen bzw abzulehnen ist einfach unsinnig und wird dir nicht helfen
 

diggaa1984

Top Contributor
ich werf mal TestNG in den Raum, eine Recht brauchbare Erweiterung von JUnit mit wesentlich feingranularerer Teststeuerung .. Daten können per Methoden oder per xml-Konfigfile eingespeist werden. Du kannst eine monströse Testklasse schreiben und den Testablauf per xml-file regeln, mittels include, exclude von Gruppen von Methoden oder wie auch immer.

Testen an sich finde ich extrem wichtig, das als "unsinnig" abzustempeln mag auf Schulniveau noch vorkommen, aber spät. in einer Ausbildung im Bereich Softwareentwicklung wird man den Sinn und den effektiven Vorteil darin erkennen.
 
B

bygones

Gast
welches Testing framework man nimmt ist nebensaechlich.. Junit, TestNG, Spock - gibt viele
 

manuche

Bekanntes Mitglied
Ganz ehrlich... Der einzige Grund warum ich JUnit einsetzen würde wäre wenn ich weiss, dass ich komplexen Sourcecode an wen anders weitergeben werde! Da hat er dann vorgefertigte Tests und weiss, dass er was falsch gemacht hat wenn der Test fehlschlägt...
Wenn die Architektur passt und sinnvolle Funktionen gefunden wurden, weiss ich als Entwickler in meinem Sourcecode selbst was am Ende bei rumkommen soll!
Ich lass mich gerne eines besseren Belehren aber ich für meine Fälle finde debuggen effizienter als ein grünes oder rotes Kästchen! Und für die komplierteren Fälle schreib ich mir nen Ablaufplan...
Mag ja echt sein, dass es Fälle gibt in denen das sinnvoll ist! Mir und weiteren 30 Leuten ist es noch nicht untergekommen! Kann aber auch an dem Bereich liegen in dem man rumwerkelt. Informatik hat viele Gesichter!
 
Zuletzt bearbeitet:
B

bygones

Gast
Ganz ehrlich... Der einzige Grund warum ich JUnit einsetzen würde wäre wenn ich weiss, dass ich komplexen Sourcecode an wen anders weitergeben werde! Da hat er dann vorgefertigte Tests und weiss, dass er was falsch gemacht hat wenn der Test fehlschlägt...
Wenn die Architektur passt und sinnvolle Funktionen gefunden wurden, weiss ich als Entwickler in meinem Sourcecode selbst was am Ende bei rumkommen soll!
Ich lass mich gerne eines besseren Belehren aber ich für meine Fälle finde debuggen effizienter als ein grünes oder rotes Kästchen! Und für die komplierteren Fälle schreib ich mir nen Ablaufplan...

man merkt dass du noch nicht viel entwickelt hast... die Annahme "wenn die Architektur passt und sinnvolle Funktionen" ist leider schon falsch.

Der Glauben man koenne alles vorher klaeren und ein sinniges, nutzbares, wiederverwendbares und wartbares Design von scratch aus erstellen ist leider voellig realitaetsfremd.

Aber ich denke jeder hat frueher nach dem Prinzip gelebt "Ich schreib fehlerfreien Code - debuggen ist dann sinnvoll und schneller"

nennt sich Cowboy hacking.

Nur wird dir das leider frueher oder spaeter so was von um die Ohren fliegen - und in einer Firma anfangen die Cowboyhacking aufm Tagesplan hat bzw das Wasserfall modell lebt == schlimme Programmierzeit
 

manuche

Bekanntes Mitglied
Gut aber dann sollte man sich mit JUnit "Just-in-Time" beschäftigen... Also lernen bzw kennenlernen (wie es hier wohl der Fall ist) um Hintergrundwisen zu haben und vertiefen wenn man es braucht!
Ist die Antwort diplomatischer? :)
 

schalentier

Gesperrter Benutzer
Gut aber dann sollte man sich mit JUnit "Just-in-Time" beschäftigen... Also lernen bzw kennenlernen (wie es hier wohl der Fall ist) um Hintergrundwisen zu haben und vertiefen wenn man es braucht!
Ist die Antwort diplomatischer? :)

Also man koennte sich auch auf den Standpunkt stellen, dass man (richtiges) Unit-Testing von Anfang lernen sollte. Nach dem Motto: Keine Klasse ohne Test (von Anfang an).

Denn das eigentliche Problem bei Unittests ist doch, dass man erst merkt, dass man sie wirklich braucht, wenn es zu spaet ist... andersrum gilt aber auch: Wenn man von Anfang an gute Tests schreibt, wird der Produktivcode automatisch um Laengen besser. Das liegt vor allem daran, weil man seine Klassen viel staerker von anderen entkoppeln muss, um vernuenftige und einfache Tests schreiben zu koennen.

Allerdings weiss ich nicht, ob das paedagogisch auch sinnvoll waere...
 

manuche

Bekanntes Mitglied
Die Frage ist glaub ich wirklich: "ab wann ist es sinnvoll"
Ich meine ich habe es ja schiesslich auch gelernt und angewendet, zugegeben anhand von blöden und simplen Beispielen, aber mir fällt einfach kein Beispiel ein, bei dem es mir persönlich einen zeitlichen Vorteil gebracht hätte...
Auf jeden Fall habe ich OO und dergleichen mehr mit ausprobieren und dergleichen gelernt! JUnit sagt dir ja auch "nur", dass irgendwo ein Fehler ist... Suchen muss man ja nachwievor selber!
 

schalentier

Gesperrter Benutzer
Das bringt keinen Zeitvorteil bei kleinen Beispielen. Im Gegenteil, Tests schreiben kostet viel Zeit. Extrem viel Zeit kostet es, fuer bestehenden Code Tests zu schreiben.

Der Vorteil kommt erst viel spaeter - wenn du Bug #32811 gefixt hast und deswegen 7 neue Tickets reinkommen, dann bekommst du eine Ahnung davon, WIE sinnvoll und zeitsparend Tests gewesen waeren.
 

manuche

Bekanntes Mitglied
Gut,
in diesen Genuß bin ich natürlich noch nicht gekommen... Zum Glück! :D
Aber kann man sich jetzt darauf einigen, dass man wissen sollte worum es geht und es einsetzen sollte wenn es wirklich Sinn macht?
Wie gesagt, bis jetzt hab ich persönlich noch keinen Nutzen davon gehabt, und wenn es dann mal gehakt hat gab es andere Möglichkeiten abhilfe zu schaffen! Mir ist natürlich Bewusst, dass sowas nur ein Fall von vielen ist...
Aber gerade wenn man dabei ist zu lernen ist es in meinen Augen nicht Produktivitäts fördernd.
 

beginner99

Aktives Mitglied
Ich habe vor kurzem auch Tests für eine User-Settings-Klasse geschrieben. Laden und Speichern werden in unabhängigen Methoden getestet. Dateien muss man dabei nicht anlegen. Die Testdaten kannst du z.B. über einen InputStream lesen bzw. in einen OutputStream speichern. Im Test leitest du diese Streams in StringBuffer um, so kannst du Testdaten für das Lesen liefern und die von der Settingsklasse geschriebenen Daten überprüfen.

Muss ich also mal ausprobieren, obwohl mir jetzt noch nicht ganz klar ist wie das gehen soll (siehe meinen Usernamen). Ist dann wohl aber gleich ein weiterer Lerneffekt.

Wie bemerkt wurde geht es hier mehr ums pädagogische, eg. ich will bzw. muss das lernen.
Aus eigener Erfahrung als Anwender bzw Admin/Verantwortlicher (beruflich) von diversen Software Produkten (Desktop, Web) würde ich jetzt auch sagen, dass sowas sehr wichtig ist. Denn bei gewissenden Lieferanten merkt man sofort, dass da irgendwo was nicht so ganz richtig ablaufen dürfte in diesem ganzen Prozess. Wenn es nicht beim Testen ist, dann spätestens bei der QC.
 

schalentier

Gesperrter Benutzer
Naja so in die Richtung:

Java:
public class AppSettings {
   private int settingA;

   public void save( Writer writer ) {..}
   public void load( Reader reader ) {..}
}

Java:
public class AppSettingsTest {
   private static final String EXPECTED_SETTINGS = "settingA=1\n";

   public void testSave() {
      AppSettings sut = createSettings( ... );
      ByteArrayOutputStream baos = new ...

      sut.save( new PrintWriter( baos ) );
      Assert.assertEquals( EXPECTED_SETTINGS, baos.toString() );
   }

   public void testLoad() { .. }
}
 
B

bygones

Gast
aber mir fällt einfach kein Beispiel ein, bei dem es mir persönlich einen zeitlichen Vorteil gebracht hätte...
immer dieses du*** Argument der zeit ... Testen ist ein Skill den man nicht mal eben hat, sondern lernen muss. D.h. natuerlich sind die ersten Schritte testen zeitintensiv, erste Schritte in Java waren auch nicht nach dem Motto "hui... 2 min dagehockt und schon eine tolle GUI".
Danach ist testen nicht mehr zeitintensiver als normales Coden, da schritte wie Refactoring oder so leichter fallen, schneller gehen und sicherer sind...

von der Zeit der Wartung zu reden lass ich mal ganz....

sorry, aber du meinst debuggen ist hilfreicher... genau das ist das zeitintensivste was es nur gibt.

JUnit sagt dir ja auch "nur", dass irgendwo ein Fehler ist... Suchen muss man ja nachwievor selber!
FALSCH... einfach nur falsch. wenn du deine Tests hast siehst du sofort welcher Teil deines Programms scheitert, du weiss unter welchen Umstaenden er genau an welcher Stelle scheitert.

Alles andere ist nur ein Indiz, dass Tests voellig falsch geschrieben wurden und nicht verstanden.


Alles in allem: Verurteile bzw lehne etwas nicht ab, wovon du leider keine Ahnung hast.


bygones


Tests werden dir in deiner Programmierlaufbahn noch ueber den Weg laufen und du kannst davon ausgehen, dass wenn du einen Job anfaengst das ein wichtiger Punkt sein wird. Und dann sagen "dann lern ich das mal eben" wird gruendlich schief gehen.

Ansonsten - klar - in der schule und normalerweise in der Uni lebt man von cowboy hacking
 
M

maki

Gast
@manuche

Die von dir beshriebenen Probleme liegen an dir, nicht an JUnit oder testen allgemein :)

Schade dass TDD heute noch nicht an den Schulen gelehrt wird...
Es gibt zB. auch sog. "Learning Tests", die helfen dir, eine neue Sprache/Framework/API zu erlernen, von Anfang an.
Gibt viel gute Literatur übers testen, sowohl in Buchform, als auch im Netz als Artikel/Blogs, einfach mal suchen.

Wenn du konkrete Fragen hast kannst du sie ja hier stellen.
 

beginner99

Aktives Mitglied
Naja so in die Richtung:

Java:
public class AppSettings {
   private int settingA;

   public void save( Writer writer ) {..}
   public void load( Reader reader ) {..}
}

Java:
public class AppSettingsTest {
   private static final String EXPECTED_SETTINGS = "settingA=1\n";

   public void testSave() {
      AppSettings sut = createSettings( ... );
      ByteArrayOutputStream baos = new ...

      sut.save( new PrintWriter( baos ) );
      Assert.assertEquals( EXPECTED_SETTINGS, baos.toString() );
   }

   public void testLoad() { .. }
}

Brauche hilfe dazu.

Wieso gebe ich den writer in die Save methode und definiere den writer nicht in der methode selbst? Die settings sind ja Felder und müssen der methode nicht übergeben werden.
Save Methode:

Java:
    public void saveSettings(Writer writer) throws IOException {

        // so hatte ich es vorher:
        //Writer output = new BufferedWriter(new FileWriter(getSettingsFilePath()));

        
        writer.write(getCurrentDrive() + System.getProperty("line.separator"));
        writer.write(getDesiredDrive() + System.getProperty("line.separator"));
        writer.write(getResumeFilePath() + System.getProperty("line.separator"));
    }

Brauche auch noch hilfe zu ByteArrayOutputStream udn wie ich das in diesem kontext verwenden soll Wie gesagt, bin anfänger.
 
B

bygones

Gast
Wieso gebe ich den writer in die Save methode und definiere den writer nicht in der methode selbst? Die settings sind ja Felder und müssen der methode nicht übergeben werden.
wenn sie felder sind dann sollten sie ueber den Konstruktor gesetzt werden.

Allgemein gesagt ist aus Testsicht immer schlecht, wenn die klasse die du testen willst ihre Abhaengigkeiten selbst erstellt.

Der Test muss das instanziieren der zu testenden Klasse und alle seiner Abhaengigkeiten im Griff haben.

Wenn du in deinem Fall den Writer selbst in der Klasse erstellst hat der Test keine chance dies zu beeinflussen - stell dir vor die Klasse erstellt einen Writer der schlussendlich auf einen Server schreibt. Wenn du dies testen wollen wuerdest muesstest du immer mit dem Server testen, testen in Isolation, wie gewuenscht, ist nicht moeglicht.

Gibst du den Writer rein, so kann der produktiv code immernoch seinen ServerWriter nutzen, der Testcode kann aber zb einen stringwriter nutzen etc etc

Ich empfehle dir mal Misko Hevery bzw die Google Clean Code Talks von misko (auf youtube)... da wird das alles genau erklaert
 

beginner99

Aktives Mitglied
wenn sie felder sind dann sollten sie ueber den Konstruktor gesetzt werden.

Ist es ok dann die loadSettings methode im Konstruktor aufzurufen? Da die aber eine IOException wefen kann, muss ich die im wieder weiter werfen(throws...)? Ist das "normal" oder sollte sowas vermieden werden?

Allgemein gesagt ist aus Testsicht immer schlecht, wenn die klasse die du testen willst ihre Abhaengigkeiten selbst erstellt.

Der Test muss das instanziieren der zu testenden Klasse und alle seiner Abhaengigkeiten im Griff haben.

Wenn du in deinem Fall den Writer selbst in der Klasse erstellst hat der Test keine chance dies zu beeinflussen - stell dir vor die Klasse erstellt einen Writer der schlussendlich auf einen Server schreibt. Wenn du dies testen wollen wuerdest muesstest du immer mit dem Server testen, testen in Isolation, wie gewuenscht, ist nicht moeglicht.

Gibst du den Writer rein, so kann der produktiv code immernoch seinen ServerWriter nutzen, der Testcode kann aber zb einen stringwriter nutzen etc etc

Das ist einleuchtend.

Momentan habe ich folgendes Problem. Ich will obige saveSettings Methode testen. èber den aufbau mag man sich streiten, die settings gehören wohl in eine List, aber das kann ich immernoch ändern.

Die TestMethode:

Java:
        private static final String EXPECTED_SETTINGS = 
            "c:\\" + System.getProperty("line.separator") +
            "d:\\" + System.getProperty("line.separator") +
            "c:\\resume.dat" + System.getProperty("line.separator");

...

@Test
    public void testSaveSettings() {
        System.out.println("saveSettings");       

        DriveChangerAppSettings appSettings =
                new DriveChangerAppSettings();

        appSettings.setCurrentDrive("c:\\");
        appSettings.setDesiredDrive("d:\\");
        appSettings.setResumeFilePath("c:\\resume.dat");
        ByteArrayOutputStream baos = 
                new ByteArrayOutputStream(EXPECTED_SETTINGS.getBytes().length);

        
        try{
         appSettings.saveSettings( new PrintWriter( baos ) );
        }

        catch(IOException ex){
            fail("An IO Exception occured during the Test.\n" + ex.getStackTrace());
        }
        //System.out.println(EXPECTED_SETTINGS);
        System.out.println(baos.toString());
        assertEquals(EXPECTED_SETTINGS, baos.toString() );
    }

Der output ist:
saveSettings // kommt von println

d:\
c:\resume.dat
]> but was:<[]>)

Der Test scheitert deshalb.
Mir ist nicht ganz klar wieso das so ist, vorallem was "]> but was:<[]>)" bedeuten soll und woher es kommt.
 
B

bygones

Gast
Im Konstruktor sollte gar nix ausser zuweisungen stehen.


Zu deinem Test:

Der Test den du aufsetzt wirkt zu fragil... sich irgendwelche strings zusammenzubasteln um diese dann irgendwie zu testen kann den Test leicht zum scheitern bringen. Du testest somit eine spezifische Implementierung, nicht eine Anforderung.

Was ich wahr in diesem Szenario testen wuerde ist, dass ich Settings habe, die wenn sie geschrieben und wieder gelesen werden immer noch die gleichen Merkmale haben (Werte oder was auch immer).

D.h. wie die persistierung ist, ist im Grunde nicht wichtig. Wichtig ist, dass das konvertieren funktioniert. Sobald du einen marginale Sache im produktiv code aenderst kann der Test fehlschlagen, obwohl das System immer noch richtig arbeitet.
 

beginner99

Aktives Mitglied
Im Konstruktor sollte gar nix ausser zuweisungen stehen.

Habe ich vermutet. Nur wo lese ich dann die settings ein? Wenn ich es nicht im Kosntruktor tue, dann muss die lesemethode nach der Objektinstanzierung aufgerufen werden (was laut deinem obigen link auch nicht gemacht werden soll).

Zu deinem Test:

Der Test den du aufsetzt wirkt zu fragil... sich irgendwelche strings zusammenzubasteln um diese dann irgendwie zu testen kann den Test leicht zum scheitern bringen. Du testest somit eine spezifische Implementierung, nicht eine Anforderung.

Was ich wahr in diesem Szenario testen wuerde ist, dass ich Settings habe, die wenn sie geschrieben und wieder gelesen werden immer noch die gleichen Merkmale haben (Werte oder was auch immer).

D.h. wie die persistierung ist, ist im Grunde nicht wichtig. Wichtig ist, dass das konvertieren funktioniert. Sobald du einen marginale Sache im produktiv code aenderst kann der Test fehlschlagen, obwohl das System immer noch richtig arbeitet.

Ich könnte jetzt sagen, ich verstehe das, aber ohne praktisch erfahrung fehlt mir wohl die komplette Einsicht.

Was ich damit sagen will, wie würdest du in meinem Beispiel konkret vorgehen?
Irgendwo muss ich dem Writer ja sagen, was er schreiben soll selbst wenn es zufallszahlen sind. Das ist das wo ich nicht ganz dahinterblicke in bezug auf deinen Post.

In meiner momentanen Situation würde es wohl auch viel helfen mal eine konrkete Lösung zu sehen, damit ich die "analysieren" kann. Bin zwar sonst fan von selbstlernen und selbsterkenntnis, aber irgendwann braucht es auch mal einen Anfangsinput.

EDIT:

Wenn ich das so betrachte müsste der writer/reader dann ja bereits dem Konstruktor übergeben werden und ein eigenes Feld sein?
 
Zuletzt bearbeitet:
B

bygones

Gast
ist natuerlich auch nur ins blinde jetzt geraten, da ich deinen speziellen Fall (was passiert eigentlich wie) nicht kenn.

naives bsp
Java:
public class FooBar {
    @Test
    public void fooBar() {
        MySettings expected = new MySettings();
        expected.setBar(42);

        MySettingsHandler handler = new MySettingsHandler();
        Writer writer = new StringWriter();
        handler.writeSettings(expected, writer);

        Reader reader = new StringReader(writer.toString());
        MySettings actual = handler.readSettings(reader);

        assertSettings(actual, expected);
    }

    private void assertSettings(MySettings actual, MySettings expected) {
        Assert.assertEquals(actual.bar, expected.bar);
    }

    public class MySettingsHandler {
        public void writeSettings(MySettings settings, Writer writer) {
            try {
                writer.write(settings.bar);
            }
            catch (IOException e) {
                throw new IllegalStateException("fehler beim schreiben", e);
            }
        }

        public MySettings readSettings(Reader reader) {
            try {
                int bar = reader.read();
                MySettings mySettings = new MySettings();
                mySettings.setBar(bar);
                return mySettings;
            }
            catch (IOException e) {
                throw new IllegalStateException("fehler beim lesen", e);
            }
        }
    }

    public class MySettings {
        private int bar;

        public void setBar(int bar) {
            this.bar = bar;
        }
    }
}
wichtig ist erstmal die Trennung zwischen der Datenklasse (MySettings) und der Persistierung (MySettingsHandler).

die Datenklasse zu testen ist sinnlos, die Persistierung ist interessanter. Hierbei sollte nicht der eigentlich mechanismus getestet werden (wie schreibt der Handler das, in ein File, eine Datenbank, als Objekt, als String) - das kann sich schnell aendern.

Wichtig ist, dass nach dem Schreiben und wieder Lesen man seine erwartetes Settings Objekt hat - und das tut der Test (wenn auch naiv)

wie du siehst ist es momentan so ausgelegt, dass der Handler nur ein Reader bzw Writer Objekt reingereicht bekommt - so kann man im Test das ueber einen String simulieren, in Produktivcode kannst du dann zb einen FileWriter bzw FileReader reinstecken.
 

schalentier

Gesperrter Benutzer
Mir ist nicht ganz klar wieso das so ist, vorallem was "]> but was:<[]>)" bedeuten soll und woher es kommt.

Die Ausgabe kommt vom assertEquals und besagt, dass "]>" erwartet (expected), aber "<[]>)" tatsaechlich geliefert (actual) wurde. Warum das in dem Beispiel so komisch aussieht, kann ich dir grad nicht erklaeren. Normalerweise sollte vor dem "but was:" der Inhalt von EXPECTED_SETTINGS stehen...

Ansonsten ist der Test okay. Du willst ja die Implementierung testen, also wuerde ich zunaechst genauso vorgehen. Sollte sich deine Implementierung aendern, wird natuerlich auch der Test fehlschlagen und muss nachgezogen werden (das meint bygones wohl mit fragil). Du wirst dann aber selbst am besten merken, welche Dinge du in eigne Methoden oder abstrakte Basisklassen auslagen kannst.

Z.B. kannst du das Stueck Code zum Erzeugen der Settings auch so schreiben:

Java:
...
public DriveChangerAppSettings createSettings( String currDir, String desiredDir, String resumePath ) {
        DriveChangerAppSettings appSettings = new DriveChangerAppSettings();
 
        appSettings.setCurrentDrive(currDir);
        appSettings.setDesiredDrive(desiredDir);
        appSettings.setResumeFilePath(resumePath);

        return appSettings;
}
public DriveChangerAppSettings createAnonymousSettings() {
        return createSettings( createRandomDir(), createRandomDir(), createRandomDir() );
}

Dann benutzt du das, um (auch in andren Tests) irgendwelche Settings zu erzeugen.

Desweiteren kannst du im Test auf das try-catch verzichten, das blaest nur unnoetig den Code auf:
Java:
public void testSaveSettings() throws IOException {
...
}

Sollte eine Exception fliegen, so schlaegt auch der Test fehl.
 

beginner99

Aktives Mitglied
wichtig ist erstmal die Trennung zwischen der Datenklasse (MySettings) und der Persistierung (MySettingsHandler).

die Datenklasse zu testen ist sinnlos, die Persistierung ist interessanter. Hierbei sollte nicht der eigentlich mechanismus getestet werden (wie schreibt der Handler das, in ein File, eine Datenbank, als Objekt, als String) - das kann sich schnell aendern.

Wichtig ist, dass nach dem Schreiben und wieder Lesen man seine erwartetes Settings Objekt hat - und das tut der Test (wenn auch naiv)

wie du siehst ist es momentan so ausgelegt, dass der Handler nur ein Reader bzw Writer Objekt reingereicht bekommt - so kann man im Test das ueber einen String simulieren, in Produktivcode kannst du dann zb einen FileWriter bzw FileReader reinstecken.

Noch folgende Fragen:

Was genau ist naiv an diesem Test?

Die settings kann man einfach in eine Map lesen. Die Frage die ich mir dann stelle ist, ob es überhaupt noch eine settings Klasse braucht oder nur den Handler. Die Settingsklasse würde ja eigentlich gar nichts tun was die Map nicht selbst kann.
(ausser den methoden schönere Namen zu geben, zb getSetting anstatt get)
->also ein Datenfeld in der "Applikationsklasse".

Sonst sage ich mal fettes Dankeschön. Das war ziemlich lehrreich und das hat mich im Verständnis der Sache (testen, wieso der Aufbau von Klassen von dir so gewählt wurde) doch einiges weitergebracht.
 
B

bygones

Gast
Noch folgende Fragen:

Was genau ist naiv an diesem Test?
mein Test war naiv da das Szenario recht erdacht war

(ausser den methoden schönere Namen zu geben, zb getSetting anstatt get)
->also ein Datenfeld in der "Applikationsklasse".
aber genau das ist wichtig und sollte nicht ausser acht gelassen werden. Bei einer eigenen Klasse kannst du die Methode getFoo anbieten, ansonsten muss der Verwender get("Foo") schreiben... und ist es nun Foo oder foo oder FoO etc etc.

Lieber auf Verwendbarkeit und Leserlichkeit achten !
 

beginner99

Aktives Mitglied
Ok.

Noch eine Frage. Ind em Bsp. verwenden wir einfach einen Reader. Dessen Methoden sind aber begrenzt. (zb readline fehlt).

Wie lese ich so am besten ein File ein?

Momentan benutze ich reader.read(charArray). Aber wie definiere ich das array sinnvoll, eg die länge. Irgendwie ist das nicht sehr anwendungsfreundlich.
 
B

bygones

Gast
zb ein BufferedReader is auch ein Reader... der kann zeilenweise einlesen
Java:
BufferedReader in = new BufferedReader(new FileReader(file));
String line;
while((line = in.readLine()) != null) {
// eine zeile im File
}
in.close();
 

beginner99

Aktives Mitglied
Ja danke. Die idee hatte ich dann auch noch.

Jetzt habe ich noch folgendes Problem:

Ich lese noch ein anderes File ein und will darin etwas ändern. Habe es mit FileReader und FileInputStream + Reader probiert. Nur es liesst immer nichts ein, also einen leeren String.

Es wird aber keine Fehlermeldung/Exception ausgegeben.
(der test läuft, aber da greife ich ja nicht auf ein file zu)

Habe mit encodings gespielt, aber macht keinen Unterschied.
 
B

bygones

Gast
wird man code brauchen um das zu wissen ;-)

vll neues Thema aufmachen und dort beschreiben
 

beginner99

Aktives Mitglied
Hat sich erledigt. Das File ist nicht wirklich lesbar. Aber ist nicht wirklich schlimm, das ganze dient ja sowieso nur dem lernzweck.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
U JUnit testen auf SomeException Java Basics - Anfänger-Themen 5
Y Wie kann ich Konsoleneingaben durch den Scanner mit JUnit 4 testen? Java Basics - Anfänger-Themen 1
B JUnit 4: Wie man die eigene Liste testen kann [TDD] Java Basics - Anfänger-Themen 46
N JUnit und private Methoden testen. Java Basics - Anfänger-Themen 9
J LocalDateTime testen mit Junit Java Basics - Anfänger-Themen 20
G Testen mit JUnit Java Basics - Anfänger-Themen 4
A IllegalArgumentException in JUnit testen Java Basics - Anfänger-Themen 3
V ToString-Methode mit JUnit testen(BlueJ) Java Basics - Anfänger-Themen 10
S Double und Gleitkommazahlen mit JUnit testen Java Basics - Anfänger-Themen 7
T Junit --Exception testen Java Basics - Anfänger-Themen 15
M JUnit - nur einzelne Methode testen? Java Basics - Anfänger-Themen 4
W Mit jUnit Array testen? Java Basics - Anfänger-Themen 5
Spin JUNIT Test Case - Problem bei testen Java Basics - Anfänger-Themen 2
turmaline JUnit testen ob keine Exception auftritt Java Basics - Anfänger-Themen 23
xehpuk In JUnit über eigenen Thread testen Java Basics - Anfänger-Themen 3
G Methoden mit Junit testen? Java Basics - Anfänger-Themen 2
A mit Junit testen Java Basics - Anfänger-Themen 7
L Methoden Eine Methode um zu testen ob es ein Nachbar gibt Java Basics - Anfänger-Themen 10
U Sortierung in collections testen Java Basics - Anfänger-Themen 11
Düsseldorf2002 Testen meines Algorithmus Java Basics - Anfänger-Themen 1
nonickatall Ausführbarkeit von Code testen bzw. Remote Debugging Java Basics - Anfänger-Themen 4
G Java Objekte auf Duplikate testen Java Basics - Anfänger-Themen 4
N Länge eines Arrays in einem Objekt testen Java Basics - Anfänger-Themen 51
T Kann jemand kurz das Programm testen? Java Basics - Anfänger-Themen 13
J RSA Verschlüsselung Testen / byte[] in Objekt umwandeln Java Basics - Anfänger-Themen 1
X Nach einem Bruch testen ob es eine ganze Zahl ist Java Basics - Anfänger-Themen 6
J Womit kann ich diese Methode testen? Java Basics - Anfänger-Themen 5
scratchy1 doppelt verkettete Liste testen Java Basics - Anfänger-Themen 8
K Testen in BlueJ Java Basics - Anfänger-Themen 2
I Erste Schritte Testen, ob eine Zahl eine Primzahl ist Java Basics - Anfänger-Themen 8
J Worte auf Gültigkeit bzgl. Alphabet testen Java Basics - Anfänger-Themen 1
T OOP Zwei Klassen Testen (Arrary Iterieren) Java Basics - Anfänger-Themen 6
K Testen von Methoden Java Basics - Anfänger-Themen 5
kilopack15 Java Array Skalarprodukt testen Java Basics - Anfänger-Themen 21
K Testen von Methoden Java Basics - Anfänger-Themen 1
R Teilinhalt eines Strings testen Java Basics - Anfänger-Themen 10
S File mit canRead() testen Java Basics - Anfänger-Themen 4
A Exception vs. Testklasse (Programm testen) Java Basics - Anfänger-Themen 2
I Programm testen, aber wie? Java Basics - Anfänger-Themen 14
W Testen auf Existenz des Verzeichnisses Java Basics - Anfänger-Themen 4
M Wie private Methoden mit Asserstions testen? Java Basics - Anfänger-Themen 3
P OOP Testen ob 2 Strings gleich sind Java Basics - Anfänger-Themen 8
B Void Mehoden Testen Java Basics - Anfänger-Themen 13
G Java Applet aus Eclipse heraus testen? Java Basics - Anfänger-Themen 6
E Arrays testen Java Basics - Anfänger-Themen 4
D Assertion Error beim Testen Java Basics - Anfänger-Themen 4
S Sortierverfahren - wie Stabilität testen (im array) Java Basics - Anfänger-Themen 3
B Testen eines Bridge-Spiels Java Basics - Anfänger-Themen 5
H Input/Output Testen ob Datei leer Java Basics - Anfänger-Themen 14
C Methode Testen Java Basics - Anfänger-Themen 12
J Programm in main Methode testen Java Basics - Anfänger-Themen 29
C Klammerung testen Java Basics - Anfänger-Themen 10
? Fehler bei Testen Java Basics - Anfänger-Themen 17
vandread Internationalisierung von einem Projekt testen? Java Basics - Anfänger-Themen 2
F Interface Testen Java Basics - Anfänger-Themen 5
T Methoden Testen und schaun ob richtiges Ergebnis? Java Basics - Anfänger-Themen 5
J Testen Java Basics - Anfänger-Themen 3
Houly Setter/Getter MEthoden testen Java Basics - Anfänger-Themen 4
J Hash-Maps / ArrayLists testen Java Basics - Anfänger-Themen 12
A Programm mit Daten einer Datei testen Java Basics - Anfänger-Themen 4
G netzwerkapplikationen testen Java Basics - Anfänger-Themen 7
S Testen ob ein String ein Datum ist. Java Basics - Anfänger-Themen 5
T Testen ob eine Zahl im array doppel vorkommt. Java Basics - Anfänger-Themen 7
G *.java Datei mit Editor starten und testen Java Basics - Anfänger-Themen 6
reno Testen ob String leer ist Java Basics - Anfänger-Themen 12
G testen ob int gleich null Java Basics - Anfänger-Themen 15
G testen ob in String zahl Java Basics - Anfänger-Themen 10
K Program Testen mit Macintosh Java Basics - Anfänger-Themen 2
F Testen ob Double-Variable Java Basics - Anfänger-Themen 13
G SSL Verbindung testen? Java Basics - Anfänger-Themen 1
M Kostenloser webspace zum testen von Javaprogrammen ? Java Basics - Anfänger-Themen 3
G Baum testen Java Basics - Anfänger-Themen 20
H Testen, ob Thread schläft Java Basics - Anfänger-Themen 3
S Testen ob ein Char Array noch nicht belegt ist! Java Basics - Anfänger-Themen 3
M Testen ob ein Sample noch abgespielt wird Java Basics - Anfänger-Themen 6
G wie eine selbstgeschriebene Klasse testen? Java Basics - Anfänger-Themen 15
P programm testen ohne main-funktion Java Basics - Anfänger-Themen 19
B Klammerung testen Java Basics - Anfänger-Themen 12
W junit.Test not accessible? Java Basics - Anfänger-Themen 4
6 Best Practice Feedback zu Service / JUnit Tests Java Basics - Anfänger-Themen 3
M Anfängerfehler - Tests JUnit IntelliJ Java Basics - Anfänger-Themen 24
D Cannot find JUnit.framework Java Basics - Anfänger-Themen 1
W Junit-Test (Java) Java Basics - Anfänger-Themen 4
W Testfälle bei Java ( Junit-Test) Java Basics - Anfänger-Themen 3
U jUnit 5 Test für eine addMethode Java Basics - Anfänger-Themen 18
A JUnit testing is inkonsistent Java Basics - Anfänger-Themen 12
A Junit Test für MysqlDataSource JDBC Java Basics - Anfänger-Themen 3
A Test Junit Java Basics - Anfänger-Themen 1
H Junit test Java Basics - Anfänger-Themen 12
P Methoden JUnit 4 - Test Java Basics - Anfänger-Themen 6
P Probleme mit JUnit-Tests, es kommt was anderes raus als bei manuellen Tests Java Basics - Anfänger-Themen 5
N Fehler bei JUnit Test Java Basics - Anfänger-Themen 5
W JUnit Tests Java Basics - Anfänger-Themen 4
hello_autumn Klassen Anzahl sowie die Anzahl der Junit Tests ermitteln? Java Basics - Anfänger-Themen 8
B JUnit / Exceptions/ try-catch Java Basics - Anfänger-Themen 6
L JUnit tests in java Java Basics - Anfänger-Themen 5
F JUnit - Was ist mit "side effects" gemeint ? Java Basics - Anfänger-Themen 2
H JUnit in Eclipse: java.lang.NoClassDefFoundError: Java Basics - Anfänger-Themen 9
B JUnit Test erstellen Java Basics - Anfänger-Themen 6
W Problem bei JUnit Test Aufgabe Java Basics - Anfänger-Themen 15

Ähnliche Java Themen

Neue Themen


Oben