我目前正在使用 JUnit 测试,该测试使用 ByteArrayInput 流向我的类提供输入,并使用 BytearrayOutputStream 获取输出并将其与预期输出进行比较。 当单独运行测试时,它们可以很好地通过,但是当测试整个测试类时,只有第一个通过,后续的失败,因为 OutputStream 中没有任何内容。
这是正在测试的类:
package org.oscargs;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.InputStream;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
@FunctionalInterface
interface Function {
void apply();
}
public class Menu {
private Function[] players;
private Logger logger;
private Scanner scan;
// private final PrintStream printStream;
Menu() {
logger = LogManager.getLogger();
players = new Function[2];
}
public void selectInputStream(final InputStream inputStream) {
this.scan = new Scanner(inputStream, StandardCharsets.UTF_8);
}
public void teardown() {
this.scan = null;
this.logger = null;
this.players = null;
}
public void showMenu() {
logger.info("Input command: ");
String input = scan.nextLine();
String[] parameters = input.split(" ");
if (parameters.length == 1) {
if (!parameters[0].equals("exit")){
logger.info("Bad parameters! Only available parameters are 'start <player1> <player2>' and 'exit'\n");
return;
}
logger.info("Bye\n");
// Main.endGame();
// System.exit(0);
} else if (parameters.length == 3) {
if (! parameters[0].equals("start")){
logger.info("Bad parameters! Only available parameters are 'start <player1> <player2>' and 'exit'\n");
return;
}
for (int i = 0; i < 2; i++) {
char p = Constants.getPlayerChar(i);
switch (parameters[i+1]) {
case "easy":
players[i] = () -> ComputerPlayer.moveEasy(p, Constants.EASY);
break;
case "medium":
players[i] = () -> ComputerPlayer.moveMedium(p);
break;
case "hard":
players[i] = () -> ComputerPlayer.moveHard(p);
break;
case "user":
players[i] = () -> Player.move(p);
break;
default:
logger.info("Bad parameters!");
return;
}
}
Game.init();
while(Game.continueGame) {
Game.game(players[0], players[1]);
}
} else {
logger.info("Bad parameters!");
}
}
}
这是我的测试课
package org.oscargs;
import org.junit.jupiter.api.*;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import java.io.*;
import static org.junit.jupiter.api.Assertions.*;
@ExtendWith(MockitoExtension.class)
class MenuTest {
private Menu menu;
private OutputStream outputStream;
@BeforeEach
void setUp() {
try {
this.outputStream = new ByteArrayOutputStream();
this.outputStream.flush();
System.setOut(new PrintStream(outputStream));
//// this.inputStream = new ByteArrayInputStream();
this.menu = new Menu();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@AfterEach
void tearDown() {
try {
this.outputStream.flush();
this.outputStream.close();
this.outputStream = null;
System.setOut(null);
// this.inputStream.close();
this.menu.teardown();
this.menu = null;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Test
void badCommandLenghtOneTest() {
// Given
String expectedOutput = "";
String input = "badcommand"+ System.lineSeparator();
ByteArrayInputStream in = new ByteArrayInputStream(input.getBytes());
menu.selectInputStream(in);
menu.showMenu();
String givenOutput = outputStream.toString();
expectedOutput += "Input command: ";
expectedOutput += "Bad parameters! Only available parameters are 'start <player1> <player2>' and 'exit'\n";
assertEquals(expectedOutput, givenOutput);
}
@Test
void exitCommandTest() {
// Given
String expectedOutput = "";
String input = "exit"+ System.lineSeparator();
ByteArrayInputStream in = new ByteArrayInputStream(input.getBytes());
menu.selectInputStream(in);
menu.showMenu();
String givenOutput = outputStream.toString();
expectedOutput += "Input command: ";
expectedOutput += "Bye\n";
assertEquals(expectedOutput, givenOutput);
}
}
这是错误日志
-------------------------------------------------------------------------------
Test set: org.oscargs.MenuTest
-------------------------------------------------------------------------------
Tests run: 2, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 1.452 s <<< FAILURE! -- in org.oscargs.MenuTest
org.oscargs.MenuTest.badCommandLenghtOneTest -- Time elapsed: 0.008 s <<< FAILURE!
org.opentest4j.AssertionFailedError:
expected: <Input command: Bad parameters! Only available parameters are 'start <player1> <player2>' and 'exit'
> but was: <>
at org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:151)
at org.junit.jupiter.api.AssertionFailureBuilder.buildAndThrow(AssertionFailureBuilder.java:132)
at org.junit.jupiter.api.AssertEquals.failNotEqual(AssertEquals.java:197)
at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:182)
at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:177)
at org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:1141)
at org.oscargs.MenuTest.badCommandLenghtOneTest(MenuTest.java:64)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
我正在使用 Java 17 和 JUnit 5.10.0
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
我已经尝试在执行每个测试后关闭流并将它们设置为空,以防止任何可能干扰的泄漏和打开流,并将被测类中的扫描和记录器字段设置为空,但似乎没有影响。
提前致谢
我怀疑您有某种状态从一个测试“渗透”到另一个测试(例如,在一个测试中修改然后在另一个测试中读取的静态)。
你应该重构你的类,以便
Menu
并创建一个 new Menu(...)
new Game(player1, player2)
实例并调用它的方法。要开始新游戏,您可以调用 gameInstance.reset()
或创建一个 new Game()
。