Есть ли у mockito эквивалентная идиома для jMock's States? - PullRequest
11 голосов
/ 04 июля 2011

Книга Растущее объектно-ориентированное программное обеспечение дает несколько примеров в jMock, где состояние делается явным, не раскрывая его через API.Мне очень нравится эта идея.Есть ли способ сделать это в Mockito?

Вот один пример из книги

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

Ответы [ 2 ]

7 голосов
/ 26 февраля 2014

Я использовал шпиона для того же упражнения:

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

Я изменил свой макет SniperListener в шпиона таким образом:

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

А также создал заглушенную реализацию SniperListener:

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

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

    @Override
    public void sniperWinning() {
    }
}

Книга использует "Состояния" JMock'а, но вместо этого я использовал вложенное перечисление:

private SniperState sniperState = SniperState.idle;

private enum SniperState {
    idle, winning, bidding
}

Затем вы должны использовать обычные утверждения JUnit для проверки состояния:

@Test
public void reportsLostIfAuctionClosesWhenBidding() {
    sniper.currentPrice(123, 45, PriceSource.FromOtherBidder);
    sniper.auctionClosed();
    verify(sniperListenerSpy, atLeastOnce()).sniperLost();
    assertEquals(SniperState.bidding, sniperState);
}
7 голосов
/ 04 июля 2011

Не то, чтобы я знал. Я использовал mockito очень много, и в документе нет ничего похожего на то, что я читал на сайте JMock о состояниях. Если я правильно понял, они в основном ограничивают время, в течение которого может происходить исключение, продолжительностью определенного состояния другого объекта. Это интересная идея, но я изо всех сил пытаюсь увидеть приложения для нее.

В Mockito вы можете выполнить код, используя Заглушка с обратными вызовами , чтобы выполнить ту же работу. В методе обратного вызова вы можете выполнить дальнейшие проверки состояния. В качестве альтернативы вы можете использовать Настраиваемое сопоставление аргументов , так как они также выполняются во время вызова.

Оба из них дают вам доступ к коду во время выполнения, которое является временем, когда вы хотите проверить состояние.

...