我目前正在尝试做一个垄断游戏的模拟测试课程。
我们已经获得了一些关于如何设置它的说明,但是也许我们只是误解了JMock的工作原理。
我们有使用takeTurn()
的Player类。我们有Die
,Board
和Piece
都是支持嘲笑的接口。然后,我们有了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,则默认为null
,0
,false
等值。
例如,您声明希望两次掷骰子,但是没有提供模拟的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友好得多的说法。如果您只是从模拟开始,那么现在可能是切换的好时机。