2013-03-26 13 views
5

W ramach metody mam wyjątek, który zostanie złapany, co chcę udawać.Jak wyśmiać wyjątek podczas tworzenia instancji nowej klasy przy użyciu Mockito

Wiem, jak wyśmiać obiekt, aby wyrzucić wyjątek za pomocą metody mock.doSomething(), ale muszę zdać wyjątek zdalny, gdy klasa tworzy nową instancję.

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; 
} 

Chcę móc szydzić wszystko w bloku try, ale nie rozumiem, jak wyśmiewać utworzenie nowej klasy, następujący wiersz szczególne:

bike = new Bicycle(this); 

Próbowałem wielu różnych testów Mockito, takich jak:

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

Chociaż rozumiem tę wolę i nie działa, chcę zrobić coś podobnego.

Czytałem dokumenty Mockito i nie znalazłem niczego przydatne:

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

+0

możliwe duplikat [Jak zmusić Mockito rzucać RemoteException w teście JUnit] (http://stackoverflow.com/questions/15582395/how-to-force-mockito-to-throw-remoteexception-in-junit-test) –

+0

@ ChristofferHammarström To zdecydowanie nie jest duplikat. Napisałem poprzednie pytanie i szukam dwóch różnych odpowiedzi od obu. –

Odpowiedz

3

Możesz użyć rozszerzenia Mockito, PowerMock, w takich przypadkach. Pozwala kpić z konstruktorów (patrz https://code.google.com/p/powermock/wiki/MockConstructor).

W tym przypadku można napisać coś podobnego następujący test:

@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); 
    } 
} 

Więcej przykładów można znaleźć na stronie: https://code.google.com/p/powermock/source/browse/trunk/modules/module-test/mockito/junit4/src/test/java/samples/powermockito/junit4/whennew/WhenNewTest.java

7

ty nie ogólnie mock konstruktorów. You można zrobić za pomocą narzędzi, takich jak PowerMock, ale generalnie sugeruję, nie.

Obecnie twój kod nie jest w rzeczywistości testowalny, jeśli chcesz kontrolować, co się stanie, gdy zostanie zbudowany nowy Bicycle. Czy skonstruowanie Bicycle jest właściwie złożoną operacją? Być może chcesz BicycleFactory, który można przekazać do klasy jako zależność, na przykład - następnie można wykpić BicycleFactory.createBicycle lub jakkolwiek to nazwiesz.

Konstruktory są jak statyczne metody - kiedy używasz ich, jesteś ściśle związany z konkretnym kodem, do którego dzwonisz; nie ma prostego sposobu na wstrzykiwanie innych zachowań bez podejścia takiego jak PowerMock.

+0

Nie wydaje mi się, abym wyjaśnił, ale Rower jest instancją innej klasy, a nie tą, w której obecnie znajduje się ta metoda.Metoda pobiera instancję, ale jeśli jest pusta, chcę utworzyć nową. Nie jestem pewien, czy to by coś zmieniło, czy nie? –

+0

@JohnVasiliou: Nie, wcale. Nadal dzwoni się do konstruktora - co zasadniczo nie jest czymś, co można po prostu wyśmiewać w testach. –

+0

Istnieje wiele rzeczywistych sytuacji, w których tworzenie instancji bezpośrednio jest właściwą rzeczą. Dla jednego z takich przykładów należy rozważyć klasę usług biznesowych, która musi wysłać powiadomienie za pośrednictwem poczty e-mail; w języku Java dobrze znanym interfejsem API do obsługi poczty e-mail jest [Apache Commons Email] (http://commons.apache.org/proper/commons-email), gdzie zwykle tworzone jest podklasy 'Email' (zazwyczaj' SimpleEmail'), wywołaj kilka seterów/adderów, a na końcu wywołaj metodę 'send()'. Jest prosty, obiektowy, * i * łatwy do testowania jednostkowego. –

0

Teraz Twoja getBicycle() robi co najmniej dwie rzeczy. Pobiera ("pobiera") Bicycle i tworzy Bicycle. Idealnie metoda lub klasa powinna robić tylko jedną rzecz i robić to dobrze.

Umieść obiekt w oddzielnej metodzie createBicycle() lub oddziel go BicycleFactory i wyśmiewamy.

Powiązane problemy