Question

I think I'm not using verify correctly. Here is the test:

@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
    }

Here is the code it calls:

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

Failure trace:

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)

The call I want to verify is several layers down. Is there a different way to check this?

Was it helpful?

Solution

There is an error in your test method: it's missing a necessary expectation for the GameMaster#canTakeDump(). This method needs to return true when called from the tested method (because of its use in that if statement at line 45).

OTHER TIPS

I'm not sure to understand what you are doing. Given the following Player class:

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

And the following GameMaster class:

public class GameMaster {
    public GameMaster() {
    }

    public void bar() {
    }
}

I'd write the test of Player like this:

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
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top