2016-03-29 2 views
1

Hier ist eine viel-abgespeckte Methode aus dem wirklichen Leben ... die echte Methode macht andere Dinge, aber ich habe einige seltsame Verhalten zu diesen wenigen Zeilen eingegrenzt . Betrachten wir ein Verfahren, das eine java.sql.Timestamp von einem java.util.Date zu schaffen versucht ... (geschweige denn, wenn ich in diesem Verfahren etwas falsch zu machen bin, das ist nicht der Punkt):Assertion, dass ein JMockit Erwartungsergebnis ist die gleiche Instanz wie konstruiert

public class MyTest { 

    public Timestamp convertDateToTimestamp(Date d) { 
     long l = d.getTime(); 
     Timestamp ts = new Timestamp(l); 
     return ts; 
    } 

} 

Also schreibe ich folgendes JMockit JUnit-Test Fall für diese Methode:

@RunWith(JMockit.class) 
public class MyTestTest { 

    @Tested MyTest test; 

    @Test 
    public void testConvertDateToTimestamp(@Mocked final Timestamp ts, @Mocked final Date d) throws Exception { 
     new Expectations() { 
      { 
       d.getTime(); result = 8675309l; 
       new Timestamp(8675309l); result = ts; 
      } 
     }; 

     Timestamp retval = test.convertDateToTimestamp(d); 
     assertThat(retval, sameInstance(ts)); 
    } 

} 

Notiere die Behauptung in der letzten Zeile dort ... ich dachte, dass ich sicher sein, sollte ich genau die gleiche Instanz, die meine Konstruktor erstellt bin immer.

Dieser Test ist ein sehr eigenartiges Ergebnis:

java.lang.AssertionError: 
Expected: sameInstance(<[email protected]>) 
    but: was <[email protected]> 
    at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20) 
    at com.example.dcohl.MyTestTest.testConvertDateToTimestamp(MyTestTest.java:32) 
... 

Kann das jemand erklären? Meine Assertion schlägt fehl, weil sie eine Instanz von Timestamp erwartet hat, aber statt dessen wurde ... genau dieselbe Instanz von Timestamp?

Jetzt, wenn ich auf Gleichheit, mit is(ts) anstelle von überprüfen, ist mein Test erfolgreich. Und es ist nicht kritisch, das gleiche Objekt zu sein; Gleichheit wird genügen. Aber dies ist ein Kopf-Kratzen Ergebnis ...

+0

Mit einem Debugger kann man sehen, dass 'retval' und' ts' zwei verschiedene Objekte sind, obwohl die 'toString' Methode für beide den gleichen String erzeugt. – eee

Antwort

0

Wenn ein Test eine Konstruktor Erwartung zeichnet wie new Timestamp(8675309l); result = ts;, es bedeutet nur, dass zukünftige Timestamp Instanzen durch passendes Konstruktor Anrufungen erstellt die ts Mock-Instanz logisch äquivalent sein werden (dh, sie werden das gleiche Scheinverhalten haben, wie es auf ts aufgezeichnet/verifiziert wurde. Es bedeutet nicht, dass sie dieselbe Instanz sein werden; Sie werden immer noch neue Instanzen sein.

+0

Gibt es also einen Weg, um sicherzustellen, dass ich diesen neu konstruierten 'Timestamp' und nicht einen' Timestamp' übertrage, der von einer anderen Quelle stammt? – dcsohl

+0

Ja: rufe 'convertDateToTimestamp' zweimal aus dem Test auf, übergebe dasselbe' Date' und überprüfe, ob die zurückgegebenen Referenzen auf verschiedene Instanzen zeigen. –

Verwandte Themen