#java #unit-testing #junit #junit-jupiter
Вопрос:
Я пытаюсь создать класс крестиков-ноликов и провести модульное тестирование всех методов. Прямо сейчас мой файл класса выглядит следующим образом:
public class TicTacToe { public static final Character PLAYER_1 = 'X'; public static final Character PLAYER_2 = 'O'; public static final Integer BOARD_SIZE = 3; private char[][] board; private char currentPlayer; public TicTacToe() { board = new char[BOARD_SIZE][BOARD_SIZE]; initializeBoard(); currentPlayer = PLAYER_1; } public void initializeBoard() { for(char[] row: board) { Arrays.fill(row, '-'); } } public void printBoard() { for(int i = 0; i lt; BOARD_SIZE; i ) { for(int j = 0; j lt; BOARD_SIZE; j ) { System.out.print(board[i][j]); if(j == BOARD_SIZE - 1) { System.out.println(); } else { System.out.print(" ,"); } } } } public boolean makeMove(int x, int y) { if(x gt;= BOARD_SIZE || y gt;= BOARD_SIZE || x lt; 0 || y lt; 0 || board[x][y] != '-') { return false; } board[x][y] = currentPlayer; currentPlayer = currentPlayer == PLAYER_1 ? PLAYER_2 : PLAYER_1; return true; } // more methods are below }
Если бы я хотел проверить, что printBoard() работает, когда вся доска заполнена, как бы я это сделал, не вызывая makeMove() или не делая все мои переменные класса общедоступными?
В настоящее время мой файл тестирования выглядит следующим образом:
import org.junit.*; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.io.*; import static org.junit.jupiter.api.Assertions.*; class TicTacToeTest { private final PrintStream standardOut = System.out; private final ByteArrayOutputStream outputStreamCaptor = new ByteArrayOutputStream(); @BeforeEach public void setUp() { System.setOut(new PrintStream(outputStreamCaptor)); } @org.junit.jupiter.api.Test @AfterEach public void tearDown() { System.setOut(standardOut); } @Test void initializeBoard() { } @Test void printBoard() { TicTacToe game = new TicTacToe(); game.printBoard(); assertEquals("- ,- ,-rn- ,- ,-rn- ,- ,-", outputStreamCaptor.toString() .trim()); // I want to test that a full board works for printBoard() right here. } // more testing methods below }
Я видел что-то об использовании @Jailbreak в Manifold, но я не мог заставить это работать. Если это кому-то поможет, я использую IntelliJ. Спасибо вам за любую помощь, которую вы окажете!
Ответ №1:
Три дополнительных варианта (есть и другие):
- Создайте второй конструктор TicTacToe, где вы можете перейти на предварительно заполненную доску
public TicTacToe(char[][] board)
- Добавьте дополнительный метод
public void loadBoard(char[][] board)
. - Используйте отражение для заполнения переменной платы. (плохой вариант, потому что это может привести к другому состоянию)
- Добавьте конструктор, закрытый для пакета, и пусть оба класса находятся в одном пакете.
- Создайте метод набора данных с закрытым пакетом и получите доступ к нему в части упорядочения вашего кода.
Вы также можете сделать что-то с частичным издевательством, но я думаю, что это также не лучший вариант в данной ситуации.
Еще один хороший вариант — создать отдельный класс для распечатки платы:
public class BoardPrinter { public BoardPrinter() {} public printBoard(char[][] board} { // print the board } }