Java:使用Mockito进行模拟测试

3

我认为我没有正确使用 verify。以下是测试:

@Mock GameMaster mockGM;    
Player pWithMock;

@Before
public void setUpPlayer() throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
    pWithMock = new Player(mockGM);
}

@Test
    public void mockDump() {
        pWithMock.testDump();
        verify(mockGM).emitRandom(); // fails
    }

这里是它调用的代码:

public boolean testDump() {
    Letter t = tiles.getRandomTile();
    return dump(t);
}

private boolean dump(Letter tile) {
            if (! gm.canTakeDump() || tiles.count() == 0) {
        return false;
    }

    tiles.remove(tile);
    gm.takeTile(tile);
    for (int i = 0; i < 3; i++) {
        tiles.addTile(gm.emitRandom()); // this is the call I want to verify
    }
    return true;
}

失败跟踪:

Wanted but not invoked:
gameMaster.emitRandom();
-> at nth.bananas.test.PlayerTest.mockDump(PlayerTest.java:66)

However, there were other interactions with this mock:
-> at nth.bananas.Player.dump(Player.java:45)

    at nth.bananas.test.PlayerTest.mockDump(PlayerTest.java:66)

我想要验证的调用在多层嵌套中,有没有其他方法来检查它?

2个回答

0

我不确定理解你正在做什么。给定以下 Player 类:

public class Player {
    private final GameMaster gm;

    public Player(GameMaster gameMaster) {
        this.gm = gameMaster;
    }

    public void foo() {
        gm.bar(); // this is the call we want to verify
    }
}

以及以下GameMaster类:

public class GameMaster {
    public GameMaster() {
    }

    public void bar() {
    }
}

我会这样编写Player的测试:
import static org.mockito.Mockito.verify;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class PlayerTest {

    @Mock
    private GameMaster gm;

    @Test
    public void testFoo() {
        Player player = new Player(gm);
        player.foo();
        verify(gm).bar(); // pass
    }
}

我绝对不知道我在做什么。这与我发布的有什么不同? - Nick Heiner
还有,如果GameMaster类没有无参构造函数怎么办? - Nick Heiner
@Rosarch 这有什么不同? 我不是完全确定,因为你没有展示所有的代码,但是这个可以工作 :) 如果GameMaster没有一个无参构造函数怎么办? 好吧,这只是一个示例,但如果你需要添加这个构造函数来使代码可测试,那就加上它。 - Pascal Thivent
好的,但是在你的例子中,如果 foo() 调用 odp(),然后再调用 bar()verify(gm).bar() 仍然能够检测到它吗? - Nick Heiner
@Rosarch,这不正是foo()正在做的吗?我不明白有什么区别。 - Pascal Thivent
显示剩余4条评论

0

你的测试方法中存在一个错误:缺少对 GameMaster#canTakeDump() 的必要期望。当从被测试的方法中调用时,该方法需要返回 true(因为它在第45行的那个 if 语句中使用了)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接