package de.tims.tictactoe.ai; import static org.mockito.Mockito.*; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentMatcher; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import de.tims.tictactoe.GameLogic; @ExtendWith(MockitoExtension.class) class AIEasyTest { static int size = 3; @Mock private GameLogic gl; @Test void emptyBoardChooseRandomField() { char realChar = 'o'; doReturn(new char[][] { {'-', '-', '-'}, {'-', '-', '-'}, {'-', '-', '-'} }).when(gl).getBoard(); TicTacToeAI ai = new AIEasy(gl); //run method 100 times, because of random generator for (int i = 0; i < 100; i++) { ai.calculateNextMove(); } verify(gl, times(100)).setField(intThat(new ChooseRandomFieldMatcher()), intThat(new ChooseRandomFieldMatcher()), eq(realChar)); } @Test void notEmptyBoardChooseRandomFreeField() { char realChar = 'o'; doReturn(new char[][] { {'x', '-', 'o'}, {'-', 'o', '-'}, {'-', 'x', 'x'} }).when(gl).getBoard(); TicTacToeAI ai = new AIEasy(gl); //run method 100 times, because of random generator for (int i = 0; i < 100; i++) { ai.calculateNextMove(); } verify(gl, times(100)).setField(intThat(new ChooseRandomFieldMatcher()), intThat(new ChooseRandomFieldMatcher()), eq(realChar)); //verify that the method is never called with a field which was already set verify(gl, never()).setField(0, 0, realChar); verify(gl, never()).setField(0, 2, realChar); verify(gl, never()).setField(1, 1, realChar); verify(gl, never()).setField(2, 1, realChar); verify(gl, never()).setField(2, 2, realChar); } private static class ChooseRandomFieldMatcher implements ArgumentMatcher { @Override public boolean matches(Integer argument) { return argument.intValue() >= 0 && argument.intValue() < size; } } }