所以我开发了这个非常简单的TicTacToe游戏。我想测试下面给出的方法:
public class Board {
private Scanner scan = new Scanner(System.in);
public int inputBoardSize() {
while (flag) {
System.out.print("Enter the number of grids you want to play with:");
try {
boardSize = Integer.parseInt(scan.next());
if (boardSize < 3 || boardSize > 10) {
System.out.println("Please choose a board size between 3 and 10");
continue;
}
flag = false;
break;
} catch (NumberFormatException e) {
e.getMessage();
System.out.println("Please enter a number");
continue;
}
}
printBoard(boardSize);
return boardSize;
}
但是我是单元测试的新手,需要一点帮助。我无法弄清楚如何测试两个条件
- 数字格式异常
- 当输入不在 3 到 10 之间时。
我对第二个条件的测试类是这样的:
public class BoardTest extends TestCase {
@Test
public void test() {
Board board = new Board();
String input = "2";
InputStream in = new ByteArrayInputStream(input.getBytes());
System.setIn(in);
}
}
我不知道下一步该怎么做。
可以将验证逻辑提取到单独的方法中,然后测试该方法。这样就无需交互或注入Scanner
对象。提取的代码类似于
public int inputBoardSize() {
while (flag) {
System.out.print("Enter the number of grids you want to play with:");
validateBoardSize(scan.next());
}
printBoard(boardSize);
return boardSize;
}
protected void validateBoardSize(String input) {
try {
boardSize = Integer.parseInt(input);
if (boardSize < 3 || boardSize > 10) {
System.out.println("Please choose a board size between 3 and 10");
}
else {
flag = false;
}
}
catch (NumberFormatException e) {
e.getMessage();
System.out.println("Please enter a number");
}
}
一些用于执行validateBoardSize
方法的 JUnit 测试用例是:
public class BoardTest {
private static final String OUT_OUT_BOUNDS_ERROR_MESSAGE = "Please choose a board size between 3 and 10";
private static final String NFE_ERROR_MESSAGE = "Please enter a number";
private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
private Board board;
@Before
public void setUp() {
System.setOut(new PrintStream(outContent));
board = new Board();
}
@Test
public void setBoardSizeOf2EnsureErrorMessageDisplayed() {
board.validateBoardSize("2");
assertOutOfBoundsErrorMessageDisplayed();
}
private void assertOutOfBoundsErrorMessageDisplayed() {
assertEquals(OUT_OUT_BOUNDS_ERROR_MESSAGE, outContent.toString().trim());
}
@Test
public void setBoardSizeOf3EnsureNoErrorMessageDisplayed() {
board.validateBoardSize("3");
assertNoErrorMessageDisplayed();
}
private void assertNoErrorMessageDisplayed() {
assertEquals("", outContent.toString().trim());
}
@Test
public void setBoardSizeOf4EnsureNoErrorMessageDisplayed() {
board.validateBoardSize("4");
assertNoErrorMessageDisplayed();
}
@Test
public void setBoardSizeOf9EnsureNoErrorMessageDisplayed() {
board.validateBoardSize("9");
assertNoErrorMessageDisplayed();
}
@Test
public void setBoardSizeOf10EnsureNoErrorMessageDisplayed() {
board.validateBoardSize("10");
assertNoErrorMessageDisplayed();
}
@Test
public void setBoardSizeOf11EnsureErrorMessageDisplayed() {
board.validateBoardSize("11");
assertOutOfBoundsErrorMessageDisplayed();
}
@Test
public void setBoardSizeWithInvalidNumberEnsureInvalidNumberMessageDisplayed() {
board.validateBoardSize("blah");
assertInvalidNumberMessageDisplayed();
}
private void assertInvalidNumberMessageDisplayed() {
assertEquals(NFE_ERROR_MESSAGE, outContent.toString().trim());
}
}
请注意,由于程序通过通过标准输出发送的消息表示错误(而不是抛出异常),因此测试必须拦截发送到标准输出的输出消息,并执行字符串比较以查看消息的内容。因此,在setUp()
内,标准输出的OutputStream
设置为一个OutputStream
实例,其字符串值可以通过测试方法进行比较:System.setOut(new PrintStream(outContent))
。要测试输出,您只需提取OutputStream
的字符串值:outContent.toString().trim()
。请注意,trim()
用于删除尾随换行符,因为println
会将它们包含在错误消息中。换行符对操作系统敏感,因此删除它们会使比较字符串更加简单。
有关详细信息,请参阅 JUnit 测试System.out.println()
。
添加以下构造函数:
public class Board {
private Scanner;
public Board() {
this(System.in);
}
public Board(InputStream in) {
scan = new Scanner(in);
}
}
然后,您可以在测试类时提供外部InputStream
。