如何在 class 上 运行 在 Jupiter 中进行单元测试而不调用其他方法来更改对象?
How to run unit tests in Jupiter on a class without calling other methods to alter the object?
我正在尝试制作 Tic-Tac-Toe class 并对所有方法进行单元测试。现在,我的 class 文件如下所示:
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() 或使我的所有 class 变量 public ?
目前,我的测试文件如下所示:
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("- ,- ,-\r\n- ,- ,-\r\n- ,- ,-", outputStreamCaptor.toString()
.trim());
// I want to test that a full board works for printBoard() right here.
}
// more testing methods below
}
我看到了有关在 Manifold 中使用 @Jailbreak 的信息,但我无法使其正常工作。如果它对任何人有帮助,我正在使用 IntelliJ。谢谢你的帮助!
三个可选选项(还有更多):
- 创建 TicTacToe 的第二个构造函数,您可以在其中传递到预填板
public TicTacToe(char[][] board)
- 添加一个额外的方法
public void loadBoard(char[][] board)
。
- 使用反射填充板变量。 (错误的选择,因为这会导致另一种状态)
- 添加一个包私有的构造函数,让两个 class 位于同一个包中。
- 创建包私有的 setBoard 方法并在代码的排列部分访问它。
您也可以使用部分模拟来做一些事情,但我认为在这种情况下这也不是一个好的选择。
另一个不错的选择是创建一个单独的 class 用于打印电路板:
public class BoardPrinter {
public BoardPrinter() {}
public printBoard(char[][] board} {
// print the board
}
}
我正在尝试制作 Tic-Tac-Toe class 并对所有方法进行单元测试。现在,我的 class 文件如下所示:
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() 或使我的所有 class 变量 public ?
目前,我的测试文件如下所示:
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("- ,- ,-\r\n- ,- ,-\r\n- ,- ,-", outputStreamCaptor.toString()
.trim());
// I want to test that a full board works for printBoard() right here.
}
// more testing methods below
}
我看到了有关在 Manifold 中使用 @Jailbreak 的信息,但我无法使其正常工作。如果它对任何人有帮助,我正在使用 IntelliJ。谢谢你的帮助!
三个可选选项(还有更多):
- 创建 TicTacToe 的第二个构造函数,您可以在其中传递到预填板
public TicTacToe(char[][] board)
- 添加一个额外的方法
public void loadBoard(char[][] board)
。 - 使用反射填充板变量。 (错误的选择,因为这会导致另一种状态)
- 添加一个包私有的构造函数,让两个 class 位于同一个包中。
- 创建包私有的 setBoard 方法并在代码的排列部分访问它。
您也可以使用部分模拟来做一些事情,但我认为在这种情况下这也不是一个好的选择。
另一个不错的选择是创建一个单独的 class 用于打印电路板:
public class BoardPrinter {
public BoardPrinter() {}
public printBoard(char[][] board} {
// print the board
}
}