You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复使用JAX-RS/Jersey的Spring Boot应用测试失败问题

问题:Spring Boot中JAX-RS/Jersey端点的测试修复方案

基于Spring Boot的Web层测试场景,初始使用Spring MVC控制器时,标注@SpringBootTest的测试可正常通过;但将应用重构为JAX-RS/Jersey端点替代控制器后,测试失败,需修复该测试。


场景1:使用Spring MVC控制器的正常测试

控制器代码

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 build测试通过。


场景2:切换为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!";
    }
}

Jersey配置类

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 build时测试失败。


修复方案

核心原因:MockMvc是Spring MVC专属测试工具,无法直接处理Jersey端点请求。以下两种方案可解决问题:

方案1:使用Jersey原生测试框架

步骤1:添加Jersey测试依赖

在build.gradle.kts的dependencies块中加入:

testImplementation("org.glassfish.jersey.test-framework.providers:jersey-test-framework-provider-grizzly2:3.1.5")

步骤2:修改测试类

package org.example;

import jakarta.ws.rs.core.MediaType;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class GreetingEndpointTest extends JerseyTest {

    @Override
    protected ResourceConfig configure() {
        return new JerseyConfig();
    }

    @Test
    public void helloWorld() {
        String response = target("/")
                .request(MediaType.TEXT_PLAIN)
                .get(String.class);
        assertEquals("Hello, world!", response);
    }
}

优势:无需启动完整Spring上下文,测试速度更快。


方案2:使用Spring Boot的TestRestTemplate

利用TestRestTemplate启动真实Servlet容器,可处理Jersey端点请求:

package org.example;

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 static org.junit.jupiter.api.Assertions.assertEquals;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class GreetingEndpointTest {

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    public void helloWorld() {
        String response = restTemplate.getForObject("/", String.class);
        assertEquals("Hello, world!", response);
    }
}

优势:依赖完整Spring上下文,更贴近真实运行环境,适合需要Spring Bean注入的场景。


完整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")
    // 方案1需要的Jersey测试依赖,方案2可注释
    testImplementation("org.glassfish.jersey.test-framework.providers:jersey-test-framework-provider-grizzly2:3.1.5")

    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()
}

内容的提问来源于stack exchange,提问作者MikeW

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 20:24:49