Как правильно использовать mock из Mockito

372
07 января 2017, 13:08

Есть класс который я хочу протестировать, но когда я использую mock у меня не получается нормальной замены, то есть результирующий метод в классе getWinner() не возвращает ожидаемого значения . Когда я использую реальный объект то все работает. В чем я не правильно использую mock?

Сам класс:

public class TicTacToe implements TicTacToeStart {
    // хранит партии которые можно будет сыграть в процессе игры
    private ArrayList<Play> games = new ArrayList<>();
    // хранит объекты игроков которые победили
    private ArrayList<Subject> winners = new ArrayList<>();
    //имя единственного победителя набравшего 5 побед
    private String winner;
    // for test
    void setGames(ArrayList games) {
        this.games = games;
    }
    // инициализирует объеты партий
    public void createGames() {
        for (int i = 0; i < 100; i++) {
            this.games.add(
                    new Game());
        }
    }
    // возвращает имя победителя
    @Override
    public String getWinner() {
        return this.winner;
    }
    // зацикливает игры до 5 побед
    @Override
    public void start() {
        int count = 0;
        while (checkWinner().equals("") && count < games.size()) {
            Play game = this.games.get(count);
            game.choiceSide();
            game.loopMove();
            Subject winner = game.initWinner();
            if (!winner.getName().equals("nobody")) {
                this.winners.add(winner);
            }
            count++;
        }
        this.winner = checkWinner();
    }
    // проверяет кто победил 5 раз и возвращает имя победителя
    private String checkWinner() {
        int user = 0, bot = 0;
        for (Subject winner : winners) {
            if ("user".equals(winner.getName())) {
                user++;
                if (user == 5) return "user";
            }
            if ("bot".equals(winner.getName())) {
                bot++;
                if (bot == 5) return "bot";
            }
        }
        return "";
    }
}

Тест:

    @Test
    public void whenThen() {
        // подготовка
        StubInput input = new StubInput();
        input.setAnswersStr(new String[] {
                "I", "y",
                "I", "y",
                "I", "y",
                "I", "y",
                "I", "y"});
        input.setAnswersNum(new int[] {
                1, 0, 2, 0, 1, 1, 2, 2,
                1, 0, 2, 0, 1, 1, 2, 2,
                1, 0, 2, 0, 1, 1, 2, 2,
                1, 0, 2, 0, 1, 1, 2, 2,
                1, 0, 2, 0, 1, 1, 2, 2});
        Dialog dialog = new Dialog();
        dialog.setInput(input);
        Game game = new Game();
        game.setDialogs(dialog);
        ArrayList<Play> games = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            games.add(game);
        }
        TicTacToe ticTac = new TicTacToe();
        TicTacToe spy = spy(ticTac);
        spy.setGames(games);
        spy.start();
        // действие
        String result = spy.getWinner();
        // проверка что метод вызвался и что вернул что надо но 
        // я хочу как то проверить это-же только без строчки
        // spy.setGames(games); и этого огромного стаба
        verify(spy).getWinner();
        assertEquals(result, "bot");
    }
Answer 1

По моему ощущению вы мокаете не то.

Во первых, какой смысл этой проверки?

String result = spy.getWinner();
verify(spy).getWinner();

Она не несет никакого смысла.

Во вторых, если вы хотите проверить возвращаемый результат, то мокать надо объект Game что бы получилось примерно так:

Game game = mock(Game.class);
when(game.initWinner()).thenReturn(/*объект Subject с именем bot*/);
ArrayList<Play> games = new ArrayList<>();
for (int i = 0; i < 100; i++) {
    games.add(game);
}
//запускаем игру
TicTacToe ticTac = new TicTacToe();
ticTac.setGames(games);
ticTac.start();
//проверяем результат
String result = spy.getWinner();
//сюда ещё можно добавить проверку вызовов метода на объекте game
assertEquals(result, "bot");

Ну и потом отдельным тестом можно протестировать объект Game, в частности его метод initWinner() на то, что он возвращает нужный Subject

READ ALSO
Как правильно поменять сцену в живых обоях

Как правильно поменять сцену в живых обоях

Как сделать так, чтобы при изменении настроек, сцены менялись и работали без проблем?

303
Как растянуть блок на всю высоту страницы?

Как растянуть блок на всю высоту страницы?

Вопрос по CSSЗадача: есть высокий блок-контейнер, он по высоте не помещается на один экран (например, div, в котором много параграфов), надо задать...

427
Как сделать чтобы красный блок шел после картинки , а не на ней

Как сделать чтобы красный блок шел после картинки , а не на ней

Красный блок лежит на картинке и не могу его опустить

320