Имеет ли mockito эквивалентную идиому для jMock государств?
В книге Growing Object Oriented Software приводятся несколько примеров в 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);
}
}
Ответы
Ответ 1
Я использовал шпиона для самостоятельного упражнения:
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);
}
Ответ 2
Не то, чтобы я знал. Я использовал mockito в большом количестве, и ничего в doco не было похоже на то, что я читал на сайте JMock о состояниях. Если я правильно их использую, они в основном ограничивают время, в течение которого может произойти отсрочка в течение определенного состояния другого объекта. Это интересная идея, но я изо всех сил пытаюсь увидеть приложения для нее.
В Mockito вы можете выполнить код, используя Stubbing with callbacks для выполнения той же работы. В методе обратного вызова вы можете выполнить дальнейшие проверки состояния. В качестве альтернативы вы можете использовать Пользовательский сопоставление аргументов, поскольку они также выполняются во время вызова.
Оба из них дают вам доступ к коду во время выполнения, которое является временем, когда вы хотите проверить состояние.