2009-06-05 4 views
3

Ich erstelle eine Testplattform für ein Protokollprojekt basierend auf Apache MINA. Wenn Sie in MINA Pakete empfangen, ruft die Methode messageReceived() ein Objekt ab. Idealerweise würde ich gerne eine JUnit-Methode assertClass() verwenden, sie existiert jedoch nicht. Ich spiele herum und versuche herauszufinden, was mir am nächsten kommt. Ich versuche etwas zu finden, das instanceof ähnlich ist. Dies funktioniert ohne ProblemErstellen einer assertClass() -Methode in JUnit

assertClass("Packet type is correct", SomePacket.class, receivedPacket); 

jedoch in das Experimentieren und Spielen mit dieser mein Interesse durch den instanceof Betreiber erreichte wurde:

Zur Zeit habe ich:

public void assertClass(String msg, Class expected, Object given) { 
    if(!expected.isInstance(given)) Assert.fail(msg); 
} 

Um dies zu nennen.

if (receivedPacket instanceof SomePacket) { .. } 

Wie ist instanceof Lage SomePacket zu verwenden, um das Objekt zur Hand zu verweisen? Es ist keine Instanz eines Objekts, es ist keine Klasse, was ist es ?! Sobald Sie feststellen, welcher Typ SomePacket an diesem Punkt ist, ist es möglich, meine assertClass() zu erweitern, um nicht das SomePacket.class Argument einzuschließen, anstatt SomePacket zu bevorzugen?

Antwort

0

Das Argument für instanceof ist ein Klassen-/Schnittstellenname und wird direkt als JVM-Anweisung implementiert. Als solches ist es ziemlich effizient.

http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc6.html#instanceof

Ein Vorteil Instanceof stattdessen die Klassen zu vergleichen ist, dass instanceof wird immer noch funktionieren, wenn die Klasse Proxy wurde.

Es funktioniert auch, wenn das zu prüfende Objekt null ist.

+0

Danke! Ich denke, es ist so, wie ich dachte - ich kann ein ähnliches Ergebnis nicht duplizieren und muss die .getClass() aufrufen und so vergleichen. – Mike

0

SomePacket ist eine Art, wie folgt aus:

SomePacket something = null; 

Sie können es nicht direkt zur Laufzeit in der Art und Weise verweisen, die Sie wollen. Das Klassenobjekt ist der einzige Weg, den ich kenne.

0

FYI, können Sie überprüfen

if(given == null || given.getClass() != expected) 

zu überprüfen, ob die Klasse von given ist genau die Klasse expected, nicht nur zuzuweisungskompatibel.
Ich würde dies eine assertClass und Ihren ursprünglichen Vorschlag assertInstance oder assertInstanceOf nennen.

Als Reaktion auf den Kommentar:
Meine Antwort als allgemeine Spitze gemeint war, nicht als Antwort auf Ihre ursprüngliche Frage. Ich fügte ein "FYI" hinzu, um das klarer zu machen;)

Je nachdem, was genau Sie wollen, können beide Wege sinnvoll sein.

Im folgenden Beispiel

public class Base {} 
public interface Ifc {} 

public class A{} extends Base implements Ifc 
public class B{} extends Base 

das Verhalten der oben genannten Methoden wie diese

A a=new A(); 
B b=new B(); 

assertClass(A.class, a); 
assertClass(Base.class, a); // fails, a.getClass() != Base.class 
assertClass(Ifc.class, a); // fails, a.getClass() != Ifc.class 
assertClass(B.class, b); 
assertClass(Base.class, b); // fails, b.getClass() != Base.class 
assertClass(Ifc.class, b); // fails, b.getClass() != Ifc.class 

assertInstance(A.class, a); 
assertInstance(Base.class, a); // works 
assertInstance(Ifc.class, a); // works 
assertInstance(B.class, b); 
assertInstance(Base.class, b); // works 
assertInstance(Ifc.class, b); // fails, B does not implement Ifc 

Wahrscheinlich würden Sie werden mit Ihrer Methode zu überprüfen.
Aber wenn Sie die genaue Klasse, z. um sicherzustellen, dass es nicht Proxy ist oder dass es nicht eine erweiterte Klasse ist, wäre mein Vorschlag der Weg, dies zu tun.

+0

Die Genauigkeit des Namen der Methode ist nicht das, was ich versuche, eine Antwort zu bekommen. Vielleicht war meine Liste von Fragen am Ende nicht klar. Ich bin mehr daran interessiert, wie instanceof auf das Objekt verweisen kann, wie es tut. Ich fange an, die JVM tut so etwas zu denken: if (o Instanceof Obj) == if (o.getClass() equals (Obj.class).) ? – Mike

+0

Ich habe meine Antwort aktualisiert. if (o instanceof Obj)! = if (o.getClass(). ist gleich (Obj.class))! Normalerweise (abgesehen von der speziellen Handhabung des ClassLoaders) können Sie sicher mit (o! = Null && Obj.class == o.getClass()), btw. – Huxi

2

Warum benutzen Sie nicht einfach assertEquals?

+0

Die Frage ist mehr von Interesse - wie verweist instanceof direkt auf die Klasse? FWIW Ich werde wahrscheinlich am Ende AsseEquals() verwenden müssen. Das Hauptproblem ist das Fehlerpotential. Es ist leicht, .getClass() zu vergessen. Das Schreiben mehrerer Methoden mit einem Objekt, das ein Objekt aufruft und ".getClass()" aufruft, wird dieses Niggel jedoch klar lösen. – Mike

24

Werfen Sie einen Blick auf die Hamcrest-Matcher, die jetzt in JUnit enthalten sind. Was Sie wollen ist etwas wie:

Das tut alles, was Sie brauchen, einschließlich einer anständigen Fehlermeldung bei Assertion fehlgeschlagen.

+0

Beantwortet eine andere Frage - aber es ist eine Antwort :) Danke Steve. – Mike

+0

sollte es sein 'assertThat (receivedPacket, instanceOf (SomePacket.class));' (beachten Sie die '.class') – robinst

+0

Korrigiert, danke –