感觉很愚蠢,但我不能在Sping Boot (版本2.7.1
)中使用JUnit 5测试端点。
简单地说,我想测试真实的的端点响应,所以我创建了一个测试类,如Testing the Web Layer中所述。
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.HttpStatus;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ApiDocumentationControllerIntegrationTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
public void getOpenApiDocumentationShouldReturnOk() {
assertThat(restTemplate.getForEntity("/api-docs", String.class).getStatusCode())
.isEqualTo(HttpStatus.OK);
}
}
但是当我运行测试时,TestRestTemplate
调用http://localhost:8080/api-docs
,忽略了服务器应该监听随机端口的事实。
我遗漏了什么?正如其他例子所示,我试图补充:
@LocalServerPort
private int randomServerPort;
但在本例中我在启动测试时有一个例外:
java.lang.IllegalArgumentException: Could not resolve placeholder 'local.server.port' in value "${local.server.port}"
我尝试过将0
设置为端口--框架应该将其视为随机端口--但没有成功。Spring抱怨它无法监听localhost:0
。
服务配置是空的(AKA application.yaml
是空的,我没有以其他方式设置参数),所以所有的配置值都是Spring Boot的默认值。
也许这是一个问题的假人,但从昨天开始,我一直在寻找一个解决办法,但我没有找到它。
更多详细信息
控制器
@Slf4j
@Controller
public class ApiDocumentationController {
private final Resource resourceFile;
private final ObjectMapper yamlReader;
private final ObjectMapper jsonWriter;
public ApiDocumentationController(@Value("classpath:openapi/api-documentation.yaml") Resource resourceFile,
@Qualifier("yamlReader") ObjectMapper yamlReader,
ObjectMapper objectMapper) {
this.resourceFile = resourceFile;
this.yamlReader = yamlReader;
this.jsonWriter = objectMapper;
}
@GetMapping(value = "/api-docs", produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<String> getOpenApiDocumentation() {
return Try.of(() -> yamlReader.readValue(resourceFile.getInputStream(), Object.class))
.mapTry(jsonWriter::writeValueAsString)
.map(apiDocumentation -> ResponseEntity.status(HttpStatus.OK).body(apiDocumentation))
.get(); // FIXME This forced Try::get is ugly
}
}
启动程序
@SpringBootApplication
public class AirportTravellersInsightsServiceApplication {
public static void main(String[] args) {
SpringApplication.run(AirportTravellersInsightsServiceApplication.class, args);
}
分级构建
- (这是
build.gradle
的摘录。)*
上述测试位于integrationTest
源集中。
plugins {
id 'org.springframework.boot' version '2.7.1'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
id 'jacoco'
id 'checkstyle'
id 'idea'
}
group = 'example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
repositories {
mavenCentral()
}
ext.versions = [
checkstyleVersion: "8.39",
vavrVersion: "0.10.4"
]
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
implementation "io.vavr:vavr:${versions.vavrVersion}"
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml'
// TEST
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'org.junit.jupiter:junit-jupiter-api'
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine"
testAnnotationProcessor 'org.projectlombok:lombok'
}
sourceSets {
integrationTest {
compileClasspath += sourceSets.main.output
compileClasspath += sourceSets.test.output
runtimeClasspath += sourceSets.main.output
runtimeClasspath += sourceSets.test.output
}
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
integrationTestImplementation.extendsFrom testImplementation
integrationTestRuntimeOnly.extendsFrom runtimeOnly
implementation {
exclude module: 'spring-boot-starter-tomcat'
}
}
tasks.named('test') {
useJUnitPlatform()
}
task integrationTest(type: Test, description: 'Runs integration tests.', group: LifecycleBasePlugin.VERIFICATION_GROUP) {
useJUnitPlatform()
testClassesDirs = sourceSets.integrationTest.output.classesDirs
classpath = sourceSets.integrationTest.runtimeClasspath
shouldRunAfter test
}
check.dependsOn integrationTest
1条答案
按热度按时间zpjtge221#
我建议您使用
org.springframework.test.web.servlet.MockMvc
来测试您的端点。您可以阅读this来了解为什么应该使用MockMvc
。MockMvc提供对Spring MVC测试的支持。它封装所有Web应用程序Bean并使它们可用于测试。
您可以通过以下方式执行测试:
了解更多有关使用
MockMvc
、here和here进行测试的信息。更新
还有另一种方法可以在测试类中启动
MockMvc
示例: