2013-03-26 4 views
5

Innerhalb einer Methode habe ich eine Ausnahme gefangen, die ich verspotten möchte.Wie mache ich eine Ausnahme beim Erstellen einer Instanz einer neuen Klasse mit Mockito

Ich weiß, wie ein Objekt zu verspotten, um eine Ausnahme mit mock.doSomething() zu werfen, aber ich muss eine Remote-Ausnahme auslösen, wenn eine Klasse eine neue Instanz von sich erstellt.

transient Bicycle bike = null; 

public Bicycle getBicycle() { 
    if (bike == null) { 
     try { 
      bike = new Bicycle(this); 
     } catch (RemoteException ex) { 
      System.out.println("No bikes found"); 
     } 
    } 
    return bike; 
} 

Ich möchte in der Lage sein, alles im try-Block zu verspotten, aber ich verstehe nicht, wie Sie die Erstellung einer neuen Klasse verspotten, die folgende Zeile um genau zu sein:

bike = new Bicycle(this); 

ich habe viele verschiedene Mockito Tests ausprobiert, wie zum Beispiel:

Bicycle b = mock(Bicycle.class); 
Mockito.doThrow(new RemoteException()).when(b = new Bicycle()); 

Obwohl ich diesen Willen zu verstehen und nicht funktioniert, möchte ich etwas ähnliches tun.

Ich habe die Mockito docs lesen und haben nichts nützlich gefunden:

http://site.mockito.org/mockito/docs/current/org/mockito/Mockito.html

+0

möglich Duplikat von [Wie Mockito zu zwingen Remote in JUnit-Test zu werfen]:

@RunWith(PowerMockRunner.class) @PrepareForTest({ClassUnderTest.class, Bicycle.class}) public class ConstructorMockingTest { @Test public void getBicycle() { ClassUnderTest tested = new ClassUnderTest(); whenNew(Bicycle.class).withArguments(tested).thenThrow(new RemoteException()); Bicycle bicycle = tested.getBicycle(); assertNull(bicycle); } } 

Weitere Beispiele bei gefunden werden kann:

In diesem Fall würden Sie so etwas wie die folgenden Test schreiben (http://stackoverflow.com/questions/15582395/how-to-force-mockito-to-thro-remotexception-in-junit-test) –

+0

@ ChristofferHammarström Dies ist definitiv kein Duplikat. Ich habe die vorherige Frage geschrieben und ich suche zwei verschiedene Antworten von beiden. –

Antwort

7

Sie im Allgemeinen nicht Mock Bauer. Sie können tun mit Tools wie PowerMock, aber ich würde im Allgemeinen vorschlagen, dass Sie nicht tun.

Derzeit ist Ihr Code nicht wirklich testbar, wenn Sie steuern möchten, was passiert, wenn ein neuer Bicycle erstellt wird. Ist das Konstruieren einer Bicycle eigentlich eine komplexe Operation? Vielleicht möchten Sie eine BicycleFactory, die als eine Abhängigkeit in Ihre Klasse übergeben werden kann, zum Beispiel - dann können Sie BicycleFactory.createBicycle oder was auch immer Sie es nennen.

Konstruktoren sind wie statische Methoden - wenn Sie sie verwenden, sind Sie eng an den spezifischen Code gebunden, den Sie aufrufen. Es gibt keinen sauberen Weg, um andere Verhaltensweisen ohne Ansätze wie PowerMock zu injizieren.

+0

Ich glaube nicht, dass ich es klargestellt habe, aber Fahrrad ist eine Instanz einer anderen Klasse, nicht die, in der diese Methode derzeit ist.Die Methode ruft die Instanz ab, aber wenn sie null ist, möchte ich eine neue erstellen. Ich bin mir nicht sicher, ob das irgendetwas ändern würde oder nicht? –

+0

@ JohnVasiliou: Nein, überhaupt nicht. Du rufst immer noch einen Konstruktor an - was im Grunde genommen nichts ist, was du in Tests einfach ausspionieren kannst. –

+0

Es gibt viele Situationen in der realen Welt, in denen die direkte Instanziierung der Abhängigkeit das Richtige ist. Betrachten Sie als Beispiel eine Business-Service-Klasse, die eine Benachrichtigung per E-Mail senden muss; In Java ist eine bekannte API für E-Mail [Apache Commons Email] (http://commons.apache.org/proper/commons-email), wo Sie normalerweise eine 'Email'-Unterklasse (normalerweise' SimpleEmail') instanziieren, Rufen Sie einige Setter/Addierer auf und rufen Sie schließlich die Methode 'send()' auf. Es ist einfach, objektorientiert, * und * leicht zu testen. –

0

Ihr getBicycle() macht jetzt mindestens zwei Dinge. Es ruft eine Bicycle ab ("bekommt") und erstellt eine Bicycle. Idealerweise sollte eine Methode oder Klasse nur eine Sache tun und es gut machen.

Legen Sie die Erstellung des Objekts in einer separaten Methode createBicycle() oder separate BicycleFactory und spotten Sie das.