Assert

senerd

Mitglied
Hallo!

Ich habe eben versucht mich mit "assert()" vertraut zu machen und wollte fragen, ob es Sinn macht das ständig (also überall wo möglich) im Code zu verwenden. Ich meine ist sowas schönes Design?

Ich habe mir jetzt einge Seiten durchgelesen, wo immer steht, man kann es ganz einfach anwenden... Das Problem ist nur, dass es bei mir (ich abreite mit Eclipse) nichts tut. Angeblich sollte doch eine Exception fliegen oder? Wenn ich assert(false); in meinen Code packe, passiert aber genau gar nichts. Was mache ich falsch? Danke!
 

eRaaaa

Top Contributor
Meinst du nicht viel eher
Java:
 public void registerItem(Item item) {
 
       assert false : "deine Fehlermeldung";
        
        [snip some code]
    }

Du musst dann aber Assertions noch mit -ea aktivieren beim Start (bei Eclipse unter run configurations -> Vm-Argumente eintragen)
 

senerd

Mitglied
Meinst du nicht viel eher
Java:
 public void registerItem(Item item) {
 
       assert false : "deine Fehlermeldung";
        
        [snip some code]
    }

Du musst dann aber Assertions noch mit -ea aktivieren beim Start (bei Eclipse unter run configurations -> Vm-Argumente eintragen)

Danke, aber es macht immer noch nichts.

Bei meinen arguments steht jetzt:
${build_files:-ea}

ich rufe assert so auf wie du es vorgeschagen hast.
 

eRaaaa

Top Contributor
Nur -ea eintragen bei den VM-arguments !
enableasserteclipse.gif

(Galileo Computing :: Java ist auch eine Insel – 6.6 Assertions *)
 

Final_Striker

Top Contributor
Man verwendet assert...-Methoden beim Testen von Programmen mit JUnit.
Das verwenden von assert() im "normalen" Javacode ist eher unüblich, wäre mir zumindest neu.
 

senerd

Mitglied
Man verwendet assert...-Methoden beim Testen von Programmen mit JUnit.
Das verwenden von assert() im "normalen" Javacode ist eher unüblich, wäre mir zumindest neu.

Ok, danke. Aber was bringt das dann? Vom UnitTest aus habe ich ja keinen Zugriff auf einzelne Variablen einer Funktion.

Wenn ich beispielsweise den Code von vorhin habe und ich möchte überprüfen ob item != null ist:

Java:
 public void registerItem(Item item) {
 
       assert (item =! null);
        
        [snip some code]
    }

Sowas kann ich doch in einem UnitTest gar nicht überprüfen, oder? Ich meine in Unittests verwendet man doch eher: assertEquals(arg1,arg2), etc. oder?
Ein UnitTest ist für mich immer etwas, womit ich ein abgeschlossenes Modul testen kann (also was steck ich rein, und was erwarte ich mir, was passiert). Zumindest wüsste ich nicht wie ich methodenintern variablen überprüfen sollte (oder geht sowas in einem Unittest?). Danke!
 

nw90

Mitglied
Mit assert kannst du Programmierfehler aufdecken. Wenn du eine Methode
Java:
public void doSomething(MyObject object)
{
    assert object != null: "Fehler";
    /...
}
hast, stellst du somit sicher, dass du ein Object ungleich null übergibst (precondition). Andernfalls wird eine Assertion geworfen.
Mit Unit-Tests testest du in der Regel fachliche Anforderungen.
 

senerd

Mitglied
Mit assert kannst du Programmierfehler aufdecken.
hast, stellst du somit sicher, dass du ein Object ungleich null übergibst (precondition). Andernfalls wird eine Assertion geworfen.
Mit Unit-Tests testest du in der Regel fachliche Anforderungen.

Das bedeutet aber jetzt, dass man sie eben schon im Code verwendet? Kann jemand as dazu sagen wie "sauber" die Anwendung von Assert im Code ist? Ist das nur Geschmackssache oder gibt es Argumente für/gegen die Anwendung? Danke!
 

mvitz

Top Contributor
Argument gegen die Nutzung (bei Java) ist, dass man dann auch dafür sorgen muss, dass mit dem -ea Parameter die Überprüfung überhaupt angeschaltet ist. Weiterhin kann man in vielen Fällen durch vernünftige JUnit Tests die Fälle, die man mit Assert abdecken würde auch abdecken und dann ist das Assert eigentlich "überflüssig".
 

nw90

Mitglied
In der Regel werden Assertions bei setter-Methoden verwendet. Nicht jede Set-Methode kann/soll mit jedem Wert umgehen können(z.B. null). Zwar wird häufig bei einem Setter der Wert auf null geprüft und in diesem Fall ein "Dummy-Wert" erzeugt und zugewiesen, jedoch ist dies nicht immer sinnvoll. In solchen Fällen sind Assertions als Vorbedingungen durchaus sinnvoll. Zudem werden Setter-Methoden nicht immer für sich getestet, da sie meist nur einen Wert zuweisen, z.B.
Java:
public void setName(String name)
{
    this.name = name;
}
Für eine solche Methode wird meist kein Unit-Test geschrieben. Es kann jedoch sein, dass diese Methode durch einen Programmierfehler mit null aufgerufen wird, wodurch es im weiteren Code zu Nullpointer-Exceptions kommen kann. Wenn in der Methode eine Assertion gesetzt wird, wird der Fehler sofort bemerkt und die Ursache für die Nullpointer-Exception muss nicht erst gesucht werden.
 

Fu3L

Top Contributor
In Effective Java schreibt Joshua Bloch (der den Assert-Mechanismus mit entwickelt hat), dass man Assertions für mögliche Fehler im eigenen Code verwenden sollte, da die Überprüfung fast keinen Aufwand bedeutet insbesondere, wenn später Assertions deaktiviert sind.. Für Klassen, die von externen Programmierern verwendet werden sollen, sollte man lieber normale Exceptions schmeißen..
 
M

maki

Gast
Das Standard assert sollte man nie verwenden, da es per default nicht aktiviert ist, ist ziemlich witzlos bzw. irreführend und daher gefährlich.

Man sich sich so ein Assert in 1-3 Zeilen selber schreiben ;)
Da steckt kein großer "Mechanismus dahinter...

Ich nutze JUnit und versuche immer eine hohe Testabdeckung zu haben, so fängt man solche Fehler sicher schon zur Entwicklungszeit.
 

fastjack

Top Contributor
assert != assertXXX()

d.h. Java-interne asserts entsprechen nicht den von JUnit. Es gibt aber plain old Java Tests, bei denen assert in den Testmethoden benutzt wird und die nicht auf JUnit oder ähnlichem basieren.

assert als Schlüsselwort soll man verwenden, wenn Vorbedingungen, Nachbedingungen und/oder Invarianten abgeprüft werden sollen und zwar in non-public Methoden. In public Methoden soll man das explizit selber machen, je nach Spezifikation halt.

Mit -ea werden sie aktiviert, standardmäßig sind sie aus, weil die Erfinder davon ausgegangen sind, das sie Rechenzeit fressen. Meiner Meinung nach ist es ein Problem, das sie standardmäßig deaktiviert sind. Du auch mit dem Schalter Klassen oder Packages angeben, um das An- und Ausschalten etwas zu verfeinern. Wie ich mal gelesen habe soll der Standardweg so sein, das wenn im produktiven Code ein Fehler auftritt, der Entwickler die Assertions aktiviert und versucht ihn zu reproduzieren, für mich irgendwie fragwürdig, da zeitaufwändig. Besser wäre es doch, wenn aus dem produktiven Code gleich eine IllegalArgumentException fliegt und der Entwickler anhand vom Log oder so sieht was Phase ist, oder war.

Apache hat übrigens eine nette Klasse zum Abprüfen von Vorbedingungen usw.

Validate (Commons Lang 2.5 API)

ansonsten halt:

Code:
if (item == null) {
    throw new IllegalArgumentException("hey, item cannot be null!");
}
 

Ähnliche Java Themen

Neue Themen


Oben