我们也遇到过类似的情况,使用 jersey 加 spring 作为依赖注入框架(jersey-spring-bridge)。使用JerseyTest 框架编写集成测试很棘手,因为它在测试之前启动容器并在测试之后停止容器。
这种方法可能有一个优势,但是考虑到 Spring 每次都会扫描和自动装配 bean 的事实,它非常耗时且棘手。
如何初始化一个 grizzly 容器并将其用于
一个测试类中的所有测试?
为了实现上述目的,我遵循了以下步骤:
在测试类中作为实例变量,声明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,这包括您的资源/控制器、ExceptionMapper(如果有)以及任何其他应加载的类。
- 创建一个 WebappContext 实例,然后以编程方式将所有
web.xml 上下文初始化参数(例如 applicationContext)添加到其中。其中applicationContext 包含基于弹簧的配置。
- 如果您的 web.xml 中有一个监听器,那么您需要以编程方式添加它们,如上所示
- 如果您有任何过滤器或其他内容,则需要以编程方式将它们添加到
ctx。
- 通过提供 URI 和
ResourceConfig 的实例,使用 Grizzly 实例初始化 server
- 您已经以编程方式创建了一个
WebappContext,它不过是web.xml,现在使用它的部署方法将服务器实例传递给它。这将运行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;