这个问题基于 Spring Boot 的测试 Web 层指南:
@SpringBootTest
开始;这与指南中的示例非常相似。问题是我们如何修复测试。
使用控制器测试应用程序
这与指南中的示例非常相似。这是控制器和应用程序的代码:
package org.example;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public final class GreetingController {
@GetMapping("/")
public @ResponseBody String helloWorld() {
return "Hello, world!";
}
}
package org.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class GreetingApplication {
public static void main(String[] args) {
SpringApplication.run(GreetingApplication.class, args);
}
}
这是应用程序相应的测试类:
package org.example;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
@SpringBootTest
@AutoConfigureMockMvc
public final class GreetingApplicationTest {
@Autowired
private MockMvc mvc;
@Test
public void helloWorld() throws Exception {
mvc.perform(get("/")).andExpect(status().isOk()).andExpect(content().string("Hello, world!"));
}
}
以下是代码的行为方式:
./gradlew bootRun
)并手动测试它,它就可以工作。./gradlew build
),测试就会通过。使用 JAX-RS/Jersey 端点测试应用程序
我们将对代码进行以下更改:
GreetingController
GreetingEndpoint
JerseyConfig
这是我们将添加的类的代码:
package org.example;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import org.springframework.stereotype.Component;
@Component
@Path("/")
public final class GreetingEndpoint {
@GET
public String helloWorld() {
return "Hello, world!";
}
}
package org.example;
import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.stereotype.Component;
@Component
public final class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
register(GreetingEndpoint.class);
}
}
以下是代码的行为方式:
./gradlew bootRun
)并手动测试它,它就可以工作。./gradlew build
),测试将失败。我们如何修复
GreetingEndpointTest
以使测试通过?
如果你想自己复制这个,以下是
build.gradle.kts
的内容:
plugins {
java
id("org.springframework.boot") version "3.4.0"
}
repositories {
mavenCentral()
}
dependencies {
implementation("jakarta.ws.rs:jakarta.ws.rs-api:4.0.0")
implementation("org.springframework.boot:spring-boot-starter-jersey:3.4.0")
implementation("org.springframework.boot:spring-boot-starter-web:3.4.0")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.11.3")
testImplementation("org.springframework.boot:spring-boot-starter-test:3.4.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.11.3")
testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.11.3")
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
tasks.named<Test>("test") {
useJUnitPlatform()
}
答案:
TestRestTemplate
可与JAX-RS/Jersey一起使用。MockMvc
不能与 JAX-RS/Jersey 一起使用。MockMvc
与Spring的MVC架构紧密耦合;它只能与 Spring 控制器一起使用。
测试 Web 层指南中有一个使用
TestRestTemplate
的示例。对于本题中的代码,以下测试将通过:
package org.example;
import static org.assertj.core.api.Assertions.assertThat;
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.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.test.web.server.LocalServerPort;
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public final class GreetingApplicationTest {
@LocalServerPort
private int port;
@Autowired
private TestRestTemplate restTemplate;
@Test
void helloWorld() {
assertThat(restTemplate.getForObject(String.format("http://localhost:%d", port), String.class))
.isEqualTo("Hello, world!");
}
}