这类似于使用
@WebMvcTest
测试单个控制器,只不过我们将使用真实的 Web 环境而不是模拟环境。请参阅:测试 Web 层指南。
以下是使用 JAX-RS/Jersey 端点的应用程序的代码:
端点:
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.app;
import org.example.endpoint.MathEndpoint;
import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.stereotype.Component;
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);
// register other endpoints
}
}
应用:
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.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!");
}
}
在现实世界中,
JerseyConfig
可能会注册多个端点。如何编写仅注册和测试单个端点的类似端点级测试?即使我正在测试单个端点而不是整个应用程序,我仍然想使用相同的测试堆栈:JUnit Jupiter、AssertJ 和 Spring Boot 的测试库。
(如果我们测试单个 Spring 控制器,答案是使用
@WebMvcTest
——不过对于这个问题,使用真实的 Web 环境而不是模拟环境就可以了。)
使用
@SpringBootApplication
注释与使用 @SpringBootConfiguration
、@EnableAutoConfiguration
和 @ComponentScan
注释相同。请参阅:Spring 文档中的使用@SpringBootApplication 注解。以下是我们如何定制测试应用程序:
JerseyTestConfig
。该组件将注册一个端点。@SpringBootConfiguration
和 @EnableAutoConfiguration
注释。@ComponentScan
@Import
组件,而不是使用 JerseyTestConfig
。classes
的@SpringBootTest
参数将用于将测试指向此测试应用程序。这是代码:
package org.example;
import static org.assertj.core.api.Assertions.assertThat;
import org.glassfish.jersey.server.ResourceConfig;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
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;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Component;
@SpringBootTest(classes = GreetingEndpointTest.TestApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
public final class GreetingEndpointTest {
@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!");
}
@Component
public static final class JerseyTestConfig extends ResourceConfig {
public JerseyTestConfig() {
register(GreetingEndpoint.class);
}
}
@SpringBootConfiguration
@EnableAutoConfiguration
@Import(JerseyTestConfig.class)
public static class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
}