如何在一个类上运行单元测试而不调用其他方法来改变对象?



我正在尝试创建一个井字棋类并对所有方法进行单元测试。现在,我的类文件如下所示:

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 < BOARD_SIZE; i++) {
for(int j = 0; j < 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 >= BOARD_SIZE || y >= BOARD_SIZE || x < 0 || y < 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
}

我看到一些关于使用@越狱在歧管,但我不能得到工作。如果这对你们有帮助的话,我用的是IntelliJ。谢谢你的帮助!

三个可选选项(还有更多):

  1. 创建TicTacToe的第二个构造函数,您可以传入预填充板public TicTacToe(char[][] board)
  2. 增加public void loadBoard(char[][] board)方法
  3. 使用反射填充board变量。(这是一个糟糕的选择,因为这会导致另一种状态)
  4. 添加一个包私有构造函数,让两个类驻留在同一个包中。
  5. 创建package-private setBoard方法,并在代码的arrange-部分访问它。

你也可以做一些特别的嘲弄,但我认为这在这种情况下也不是一个好的选择。

另一个不错的选择是创建一个单独的类来打印电路板:

public class BoardPrinter {

public BoardPrinter() {}
public printBoard(char[][] board} {
// print the board
}
}

相关内容