《成长面向对象软件》一书在jMock中给出了几个例子,其中状态是显式的,而不通过API公开。我真的很喜欢这个主意。莫基托有办法做到这一点吗?
以下是一书中的一个例子
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);
}
}
我用间谍做了同样的练习:
http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#13
我把我的SnipperListener模拟变成了一个间谍,这样:
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的"States",但我使用了嵌套枚举:
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);
}
我不知道。我已经使用了很多mockito,文档中没有任何内容与我在JMock网站上读到的关于各州的内容类似。如果我说得对的话,他们基本上将一个观察发生的时间限制在另一个物体的特定状态的持续时间内。这是一个有趣的想法,但我很难看到它的应用程序
在Mockito中,您可以使用带有回调的Stubbing执行代码来完成同样的工作。在回调方法中,您可以执行状态的进一步验证。或者,您可以使用自定义参数匹配器,因为它们也在调用时执行。
这两种方法都允许您在执行时访问代码,也就是您想要检查状态的时间。