2011-07-03 8 views
10

Książka Rosnące oprogramowanie zorientowane obiektowo podaje kilka przykładów w jMock, gdzie stan jest jawny bez ujawniania go za pośrednictwem interfejsu API. Naprawdę podoba mi się ten pomysł. Czy jest sposób, aby to zrobić w Mockito?Czy mockito ma odpowiednik idiomu dla stanów jMock?

Oto przykład z książki

public class SniperLauncherTest { 
    private final States auctionState = context.states("auction state") 
               .startsAs("not joined"); 

    @Test public void addsNewSniperToCollectorAndThenJoinsAuction() { 
    final String itemId = "item 123"; 
    context.checking(new Expectations() {{ 
     allowing(auctionHouse).auctionFor(itemId); will(returnValue(auction)); 

     oneOf(sniperCollector).addSniper(with(sniperForItem(item))); 
            when(auctionState.is("not joined"));  
     oneOf(auction).addAuctionEventListener(with(sniperForItem(itemId))); 
            when(auctionState.is("not joined")); 
     one(auction).join(); then(auctionState.is("joined")); 
    }}); 

    launcher.joinAuction(itemId); 
    } 
} 

Odpowiedz

7

użyłem szpiega dla siebie samego ćwiczenie:

http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#13

zmieniłem SniperListener makiety do szpiega tak:

private final SniperListener sniperListenerSpy = spy(new SniperListenerStub()); 
private final AuctionSniper sniper = new AuctionSniper(auction, sniperListenerSpy); 

A także stworzył zgaszone realizację SniperListener:

private class SniperListenerStub implements SniperListener { 
    @Override 
    public void sniperLost() { 
    } 

    @Override 
    public void sniperBidding() { 
     sniperState = SniperState.bidding; 
    } 

    @Override 
    public void sniperWinning() { 
    } 
} 

Książka wykorzystuje "Stany" JMocka , Ale użyłem zagnieżdżonego enum zamiast:

private SniperState sniperState = SniperState.idle; 

private enum SniperState { 
    idle, winning, bidding 
} 

Następnie trzeba użyć zwykłego JUnit twierdzi przetestować dla państwa:

@Test 
public void reportsLostIfAuctionClosesWhenBidding() { 
    sniper.currentPrice(123, 45, PriceSource.FromOtherBidder); 
    sniper.auctionClosed(); 
    verify(sniperListenerSpy, atLeastOnce()).sniperLost(); 
    assertEquals(SniperState.bidding, sniperState); 
} 
+1

ten sposób jest czystsze niż inne odpowiedzi. +1 –

+1

Znacznie lepiej niż jMock użyty w książce (co jest świetne, ale ma kilka wad). Nieustannie podkreślają potrzebę uczynienia kodu testowego łatwym do uchwycenia, ale z tego punktu widzenia, sądząc z perspektywy mojego początkującego, Mockito wydaje się znacznie lepszy. –

+1

Jednak 'SniperState' jest niefortunnym wyborem nazwy ... ponieważ książka wprowadza własną klasę' SniperState' na s. 154 (i to nie jest proste 'enum') ... –

7

Nie, że jestem świadomy. Użyłem mockito za dużo i nic nie jest w dokumencie podobne do tego, co czytałem na stronie JMock o stanach. Jeśli mam go poprawnie, zasadniczo ograniczają czas, w którym może nastąpić egzekucja do czasu określonego stanu innego obiektu. To ciekawy pomysł, ale staram się zobaczyć jego aplikacje.

W Mockito można wykonać kod przy użyciu Stubbing with callbacks, aby wykonać to samo zadanie. W metodzie wywołania zwrotnego można wykonać dalsze sprawdzanie stanu. Alternatywnie możesz użyć Custom argument matcher, ponieważ są one również wykonywane w momencie połączenia.

Oba dają dostęp do kodu w czasie wykonywania, który jest czasem, w którym chcesz sprawdzić stan.