2013-05-06 17 views
5

Mam następujące klasy:PowerMockito: jak wyśmiewać metody wywoływane przez konstruktora?

public class Foo { 

    public Foo() { 
    initField1(); 
    initField2(); 
    initField3(); 
    } 

} 

muszę zmienić zachowanie (mock) initField1() i initField3() dla nich co zrobić nic, lub coś innego, że faktycznie robią. Jestem zainteresowany wykonaniem rzeczywistego kodu initField2().

Chcę napisać następujący test:

Foo foo = new Foo(); 
assertTrue(foo.myGet()); 

myGet() zwraca atrybut Foo, który został obliczony przez initField2().

Metody initField() są oczywiście prywatne.

Jak mogę zrobić coś takiego?

Dzięki za pomoc i pozdrawiam.

Odpowiedz

-1

Myślę, że coś jest nie tak z tym, co chcesz zrobić.

O ile rozumiem, szydercze ramy, takie jak Mockito lub PowerMock, mają na celu kpić z interakcji między testowanym obiektem a jego zależnościami.

Jak rozumiem twoje pytanie, chcesz wyśmiać część zachowania obiektu i przetestować resztę.

W twoim przypadku, chcesz przetestować coś, co nigdy nie nastąpi, jak initField2() nigdy nie zostanie wywołana bez połączeń do initField1() i initField3()

Jeśli powodem nie chcesz zadzwonić initField1() i dlatego te initField3 metody interakcji z innymi obiektami, lub systemu plików lub DB, powinieneś raczej wstrzyknąć zależności za pomocą argumentu konstruktora lub adnotowanych ustawiaczy i po prostu wstrzykiwać mocks dla twoich testów. Aby utworzyć obiekt z odpowiednio skonfigurowanymi zależnościami, użyj wzorca fabryk, wzorca budowniczego, a nawet lepiej, użyj szkieletu zależności wtrysku, na przykład ze Springa lub Google Guice.

Jeżeli powód d'ont chcesz zadzwonić initField1() i initField3 dlatego mają do czynienia z inną logiką biznesową w swoim obiekcie, to pachnie (jak w http://martinfowler.com/books/refactoring.html) jak łamiesz zasada jednej odpowiedzialności, a zalecana refactor.

+0

To jest starsza wersja kodu. Wolę nie modyfikować testowanej klasy, pisząc nowy konstruktor przyjmujący argumenty na przykład. Chcę, aby wykonano tylko 'initField2()', ponieważ odpowiada za ustawienie pola, które chcę przetestować. Nie interesuje mnie testowanie reszty logiki konstruktora. –

+0

Mockito ma na celu udawać interakcję, PowerMock ma na celu wyśmiać częściowe, wewnętrzne działanie klasy dla starszego kodu, więc ta odpowiedź jest po prostu błędna. – eis

5

Biorąc pod uwagę, wszystko może się zdarzyć w starszych kod :) można użyć PowerMock aby wyciszyć sposobów opisanych w http://code.google.com/p/powermock/wiki/SuppressUnwantedBehavior

import static org.powermock.api.support.membermodification.MemberMatcher.methods; 
import static org.powermock.api.support.membermodification.MemberModifier.suppress; 

@RunWith(PowerMockRunner.class) 
@PrepareForTest(Foo.class) 
public class FooTest { 

    @Test 
    public void testSuppressMethod() throws Exception { 
     suppress(methods(Foo.class, "initField1", "initField3")); 
     Foo foo = new Foo(); 
    } 
} 

Mimo to, należy ponownie czynnik klasę po masz odpowiedniego pokrycia testowego dla niego .

+0

Wielkie dzięki. Teraz działa! Jeszcze jedno pytanie, jak mogę sprawdzić, czy 'initField2()' zostało wywołane? Myślałem o szpiegowaniu mojego nowego Foo, ale tak naprawdę nie ma interakcji z nim, więc 'verifyPrivate (foo) .invoke (initField2)' nie pomaga. –

+0

@JulienCollah testujesz to pośrednio, sprawdzając, czy 'foo.myGet()' zwraca poprawną wartość. –

Powiązane problemy