Spring 启动控制台应用程序导致 JUnit 测试用例等待
Spring Boot console application causes JUnit test case to wait
我有 Spring 接受用户输入的引导控制台应用程序。在同一个应用程序中,有执行某些逻辑的服务。
在 运行直接连接服务的 JUnit 测试用例时,我观察到控制台应用程序处于接受用户输入状态的行为,因此没有进入 JUnit 测试。
通常没有问题,因为对于正常的 Spring 引导应用程序,启动时 运行 没有任何问题。但是对于此控制台应用程序设置,它等待用户输入。
请问有什么方法可以让测试用例 运行 不触发控制台应用程序吗?非常感谢。
观察:控制台应用程序在 JUnit 测试用例上触发 运行,未输入测试用例
主要应用
import java.io.BufferedReader;
import java.io.InputStreamReader;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ToyRobotApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(ToyRobotApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
// Instruct user to perform input
System.out.println("Welcome to toy robot application!");
System.out.println("Below are the possible operations:");
System.out.println("PLACE <x-coordinate> <y-coordinate> <facing>");
System.out.println("MOVE");
System.out.println("LEFT");
System.out.println("RIGHT");
System.out.println("REPORT");
while (true) {
System.out.println("Please enter your command:");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String usrInput = br.readLine();
//...
}
}
}
测试用例
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import com.somecompany.model.Facing;
import com.somecompany.model.Location;
import com.somecompany.model.Robot;
import com.somecompany.service.ToyRobotService;
@SpringBootTest
public class ToyRobotReportTest {
@Autowired
private Robot robot;
@Autowired
private ToyRobotService toyRobotService;
@Test
public void shouldBeAbleToReportLocation() {
Location location = new Location();
location.setXCor("1");
location.setYCor("2");
location.setFacing(Facing.NORTH);
robot.setLocation(location);
// Actual result
String result = toyRobotService.report();
// Assertion
assertEquals("1,2,NORTH", result);
}
}
注:省略其他来源
经过一番研究,我的设置工作正常。为了让它工作,JUnit 测试 class 不应使用通常的 @SpringBootTest 注释进行注释。
当 class 被注释为 @SpringBootTest 时,它将启动应用程序的上下文(即启动应用程序)。在大多数常见的测试场景中,如果没有等待用户输入,这应该没问题。
在我们的例子中,我们希望识别 Spring 引导注释(例如@Autowired),但不希望启动应用程序本身。
我们可以在 JUnit 中使用以下内容:
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = ToyRobotApplication.class, initializers = ConfigDataApplicationContextInitializer.class)
public class ToyRobotPlaceTest {
...
}
这将重新定义 spring 注释,但不会启动应用程序上下文。
我有 Spring 接受用户输入的引导控制台应用程序。在同一个应用程序中,有执行某些逻辑的服务。
在 运行直接连接服务的 JUnit 测试用例时,我观察到控制台应用程序处于接受用户输入状态的行为,因此没有进入 JUnit 测试。
通常没有问题,因为对于正常的 Spring 引导应用程序,启动时 运行 没有任何问题。但是对于此控制台应用程序设置,它等待用户输入。
请问有什么方法可以让测试用例 运行 不触发控制台应用程序吗?非常感谢。
观察:控制台应用程序在 JUnit 测试用例上触发 运行,未输入测试用例
主要应用
import java.io.BufferedReader;
import java.io.InputStreamReader;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ToyRobotApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(ToyRobotApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
// Instruct user to perform input
System.out.println("Welcome to toy robot application!");
System.out.println("Below are the possible operations:");
System.out.println("PLACE <x-coordinate> <y-coordinate> <facing>");
System.out.println("MOVE");
System.out.println("LEFT");
System.out.println("RIGHT");
System.out.println("REPORT");
while (true) {
System.out.println("Please enter your command:");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String usrInput = br.readLine();
//...
}
}
}
测试用例
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import com.somecompany.model.Facing;
import com.somecompany.model.Location;
import com.somecompany.model.Robot;
import com.somecompany.service.ToyRobotService;
@SpringBootTest
public class ToyRobotReportTest {
@Autowired
private Robot robot;
@Autowired
private ToyRobotService toyRobotService;
@Test
public void shouldBeAbleToReportLocation() {
Location location = new Location();
location.setXCor("1");
location.setYCor("2");
location.setFacing(Facing.NORTH);
robot.setLocation(location);
// Actual result
String result = toyRobotService.report();
// Assertion
assertEquals("1,2,NORTH", result);
}
}
注:省略其他来源
经过一番研究,我的设置工作正常。为了让它工作,JUnit 测试 class 不应使用通常的 @SpringBootTest 注释进行注释。
当 class 被注释为 @SpringBootTest 时,它将启动应用程序的上下文(即启动应用程序)。在大多数常见的测试场景中,如果没有等待用户输入,这应该没问题。
在我们的例子中,我们希望识别 Spring 引导注释(例如@Autowired),但不希望启动应用程序本身。
我们可以在 JUnit 中使用以下内容:
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = ToyRobotApplication.class, initializers = ConfigDataApplicationContextInitializer.class)
public class ToyRobotPlaceTest {
...
}
这将重新定义 spring 注释,但不会启动应用程序上下文。