如何测试使用 JAX-RS/Jersey 的 Spring Boot 应用程序?

问题描述 投票:0回答:1

这个问题基于 Spring Boot 的测试 Web 层指南:

  1. 我们将从使用控制器时传递的
    @SpringBootTest
    开始;这与指南中的示例非常相似。
  2. 我们将重构 Spring Boot 应用程序以使用 JAX-RS/Jersey 端点而不是控制器;现在测试失败了。

问题是我们如何修复测试。

使用控制器测试应用程序

这与指南中的示例非常相似。这是控制器和应用程序的代码:

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()
}
spring-boot jersey
1个回答
0
投票

答案:

  • 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!");
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.