问题 mockito与jMock的州有相同的习惯用语吗?


这本书 不断发展的面向对象软件 在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);
   }
}

8983
2017-07-03 22:38


起源



答案:


我使用间谍进行同样的练习:

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

7
2018-02-26 16:44



这种方式比其他答案更清晰。 +1 - Narendra Pathai
比书中使用的jMock好很多(这很好,但有一些缺陷)。他们经常强调需要使测试代码易于掌握,但从这个角度来看,无论如何从我的新手的角度来看,Mockito似乎远远优越。 - mike rodent
然而, SniperState 是一个不幸的名字选择...因为这本书介绍了自己的名字 SniperState 第二课。 154(并不简单 enum)... - mike rodent


答案:


我使用间谍进行同样的练习:

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

7
2018-02-26 16:44



这种方式比其他答案更清晰。 +1 - Narendra Pathai
比书中使用的jMock好很多(这很好,但有一些缺陷)。他们经常强调需要使测试代码易于掌握,但从这个角度来看,无论如何从我的新手的角度来看,Mockito似乎远远优越。 - mike rodent
然而, SniperState 是一个不幸的名字选择...因为这本书介绍了自己的名字 SniperState 第二课。 154(并不简单 enum)... - mike rodent


不是我知道的。我已经使用了很多的模拟,并且doco中的任何内容都与我在JMock网站上关于状态的内容类似。如果我有正确的话,它们基本上限制了在另一个对象的特定状态的持续时间内发生检测的时间。这是一个有趣的想法,但我很难看到它的应用程序。

在Mockito中,您可以使用执行代码 与回调结合 做同样的工作。在回调方法中,您可以执行状态的进一步验证。或者你可以雇用一个 自定义参数匹配器 因为它们也是在通话时执行的。

这两个都允许您在执行时访问代码,这是您要检查状态的时间。


7
2017-07-03 23:54