我们也遇到过类似的情况,使用 jersey 加 spring 作为依赖注入框架(jersey-spring-bridge)。使用框架编写集成测试JerseyTest
很棘手,因为它在测试之前启动容器并在测试之后停止容器。这种方法可能有一个优势,但是考虑到 Spring 每次都会扫描和自动装配 bean 的事实,它非常耗时且棘手。
如何初始化一次灰熊容器并将其用于测试类中的所有测试?
为了实现上述目的,我遵循了以下步骤:
在测试类中作为实例变量,声明一个实例HttpServer
如下
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:applicationContext.xml" })
public class OrderResourceTest {
...
public static final String BASE_URI = "http://localhost:8989/";
private static HttpServer server = null;
...
...
}
请注意,我不使用JerseyTest
是因为我想自己处理测试容器的启动/停止。现在,您需要使用@Before
并@AfterClass
设置服务器实例。在@Before
我们将设置server
实例,使其加载我们的自定义过滤器/侦听器定义web.xml
(如以编程方式将 web.xml 加载到server
实例中)
@Before
public void setUp() throws Exception {
if (server == null) {
System.out.println("Initializing an instance of Grizzly Container");
final ResourceConfig rc = new ResourceConfig(A.class, B.class);
WebappContext ctx = new WebappContext() {};
ctx.addContextInitParameter("contextConfigLocation", "classpath:applicationContext.xml");
ctx.addListener("com.package.something.AServletContextListener");
server = GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);
ctx.deploy(server);
}
}
如果你注意到我正在使用@Before 但是,if 条件将使它像@BeforeClass 一样起作用。不完全记得我为什么不使用@BeforeClass
,我的猜测可能是由于 if 块中的一些配置。无论如何,如果您好奇,请尝试一下。
- 使用要测试的资源创建 ResourceConfig,这包括您的 Resource/Controller、ExceptionMapper(如果有)以及应加载的任何其他类。
- 创建 WebappContext 的实例,然后以编程方式将所有
web.xml
上下文初始化参数添加到其中applicationContext
,例如。其中applicationContext
包含基于弹簧的配置。
- 如果您的 web.xml 中有一个侦听器,那么您需要以编程方式添加它们,如上所示
- 如果您有任何过滤器或其他东西,那么您需要以编程方式将它们添加到
ctx
.
server
通过提供 URI 和实例来使用 Grizzly 实例进行初始化ResourceConfig
- 您已经以编程方式创建了
WebappContext
web.xml,现在使用它的 deploy 方法将服务器实例传递给它。这将运行WebappContext
配置并将其部署到server
实例。
现在你有一个运行 Grizzly 实例的测试,你的 web.xml 加上应用于实例的特定于 spring 的配置。
@AfterClass
可能如下所示
@AfterClass
public static void tearDown() throws Exception {
System.out.println("tearDown called ...");
if (server != null && server.isStarted()) {
System.out.println("Shutting down the initialized Grizzly instance");
server.shutdownNow();
}
}
以及使用 REST 保证框架的示例测试
@Test
public void testGetAllOrderrs() {
List<Orders> orders= (List<Orders>)
when().
get("/orders").
then().
statusCode(200).
extract().
response().body().as(List.class);
assertThat(orders.size()).isGreaterThan(0);
}
上面没有指定基本路径的原因是因为我设置了 REST-assured 基本路径如下
RestAssured.baseURI = "http://localhost:8989/";
如果您不想使用 REST-assured 那么
@Test
public void testGetAllOrders() {
Client client = ClientBuilder.newBuilder().newClient();
WebTarget target = client.target(BASE_URI);
Response response = target
.path("/orders")
.request(MediaType.APPLICATION_JSON)
.get();
assertThat(response.getStatus()).isEqualTo(200);
JSONArray result = new JSONArray(response.readEntity(String.class));
assertThat(result.length()).isGreaterThan(0);
}
基于泽西岛的进口
import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.grizzly.servlet.WebappContext;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;