【问题标题】:jMock fails regardless of expectations无论期望如何,jMock 都失败了
【发布时间】:2014-03-27 11:46:14
【问题描述】:

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

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

我们有使用 takeTurn() 的 Player 类。我们有DieBoardPiece,这些都是支持嘲讽的接口。然后我们有 Square 类,它不保存任何值,但只是用来表示一个 Square。也许我们应该让它成为一个接口,因为它什么都没有,但我不知道。

无论我们做什么,测试总是失败。我试图省略部分,这样我们也只做一个期望,但没有运气。我们只是完全误解了 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 失败消息会很有帮助。

标签: java jmock


【解决方案1】:

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

后一项任务是您在当前代码中遗漏的内容。您需要告诉 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 使用起来更友好的 cmets。如果您刚开始模拟,那么现在可能是转换的好时机。

【讨论】:

  • 在我们看到的教程中,根本不需要返回值。
  • @Vipar 看看你的例子,我认为你需要它们。但是,在某些情况下,它们不是必需的。
  • 嗯,它奏效了。谢谢!也会看看那个 Mockito 的东西。
猜你喜欢
  • 1970-01-01
  • 2023-02-25
  • 1970-01-01
  • 2018-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多