我目前正在尝试做一个垄断游戏的模拟测试课程。

我们已经获得了一些关于如何设置它的说明,但是也许我们只是误解了JMock的工作原理。

我们有使用takeTurn()的Player类。我们有DieBoardPiece都是支持嘲笑的接口。然后,我们有了Square类,该类不包含任何值,而仅用于表示一个Square。也许我们应该使其成为一个接口,因为它什么也不容纳,但我不知道。

无论我们做什么,测试总是失败。我已尝试省略零件,以便我们也仅执行一项Expectation,但没有运气。我们只是完全误解了JMock吗?

这是我们的Player类:

public class Player {

    Die d;
    Piece p;
    Board b;

    void takeTurn(Die d, Piece p, Board b) {
        this.d = d;
        this.p = p;
        this.b = b;

        int i = d.roll();
        int v = d.roll();

        Square newLoc = b.getSquare(p.getLocation(), i + v);
        p.setLocation(newLoc);
    }
}


这是我们的PlayerTest类:

public class PlayerTest extends TestCase {

    Mockery context = new Mockery();


    public void testTakeTurn() {
        final Board b = context.mock(Board.class);
        final Piece p = context.mock(Piece.class);
        final Die d = context.mock(Die.class);

        Player pl = new Player();

        context.checking(new Expectations() {{
            exactly(2).of (d).roll();
        }});

        context.checking(new Expectations() {{
            oneOf (p).getLocation();
        }});

        final int diceroll = 5;

        context.checking(new Expectations() {{
            oneOf (b).getSquare(p.getLocation(), diceroll);
        }});

        final Square newLoc = new Square();

        context.checking(new Expectations() {{
            oneOf (p).setLocation(newLoc);
        }});

        pl.takeTurn(d,p,b);

        context.assertIsSatisfied();
    }
}

最佳答案

模拟背后的想法是,您产生可以设定期望值的伪造对象。期望包括将调用哪些方法以及从这些方法返回哪些结果。

后一个任务是您在当前代码中错过的事情。您需要告诉JMock模拟对象上的方法调用将返回什么值。如果未告知JMock,则默认为null0false等值。

例如,您声明希望两次掷骰子,但是没有提供模拟的Dice对象应返回的返回值。因此,JMock将仅返回0。稍后,您假设这两个滚动加到5,这是错误的。

您的代码应更改为大致(未经测试):

public class PlayerTest extends TestCase {

    Mockery context = new Mockery();

    public void testTakeTurn() {
        final Board b = context.mock(Board.class);
        final Piece p = context.mock(Piece.class);
        final Die d = context.mock(Die.class);

        Player pl = new Player();
        final int roll1 = 2;
        final int roll2 = 3;

        context.checking(new Expectations() {{
            exactly(2).of (d).roll();
            will(onConsecutiveCalls(
              returnValue(roll1),
              returnValue(roll2))
        }});

        final Location currentLocation = // set to your desired test loc...

        context.checking(new Expectations() {{
            oneOf (p).getLocation();
            will(returnValue(currentLocation));
        }});

        final Square newLoc = new Square();

        context.checking(new Expectations() {{
            oneOf (b).getSquare(currentLocation, roll1 + roll2);
            will(returnValue(newLoc));
        }});


        context.checking(new Expectations() {{
            oneOf (p).setLocation(newLoc);
        }});

        pl.takeTurn(d,p,b);

        context.assertIsSatisfied();
    }
}


就像我曾经爱过JMock一样,我必须同意Mockito友好得多的说法。如果您只是从模拟开始,那么现在可能是切换的好时机。

10-06 09:42