【问题标题】:Does mockito have an equivalent idiom to jMock's States?mockito 是否有与 jMock 的 States 等效的成语?
【发布时间】:2011-07-03 22:38:34
【问题描述】:

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

【问题讨论】:

    标签: java testing mocking mockito jmock


    【解决方案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 的“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);
    }
    

    【讨论】:

    • 这种方式比其他答案更干净。 +1
    • 比书中使用的 jMock 好很多(很棒,但有一些缺陷)。他们不断强调让测试代码易于掌握的必要性,但从这个角度来看,无论如何,从我的新手的角度来看,Mockito 似乎要优越得多。
    • 但是,SniperState 是一个不幸的名称选择...因为本书在第 1 页引入了自己的 SniperState 类。 154(而且不是简单的enum)...
    【解决方案2】:

    我不知道。我已经大量使用了 mockito,但 doco 中没有任何内容与我在 JMock 网站上读到的关于状态的内容相似。如果我正确地理解它,它们基本上将发生异常的时间限制为另一个对象的特定状态的持续时间。这是一个有趣的想法,但我很难看到它的应用程序。

    在 Mockito 中,您可以使用 Stubbing with callbacks 执行代码来完成相同的工作。在回调方法中,您可以执行状态的进一步验证。或者,您可以使用Custom argument matcher,因为它们也在调用时执行。

    这两种方法都可以让您在执行时访问代码,也就是您要检查状态的时间。

    【讨论】:

      猜你喜欢
      • 2012-01-10
      • 2017-04-15
      • 2014-08-14
      • 1970-01-01
      • 1970-01-01
      • 2022-06-30
      • 2012-12-01
      • 1970-01-01
      • 2014-12-19
      相关资源
      最近更新 更多