我正在努力修复其中一个项目中的集成测试。目前,所有集成测试类都扩展了JerseyTest类。通过JerseyTest class我意识到它使用Junit的Before和After注释为每个测试方法启动和停止容器。
为什么这有必要?如果我们提起容器一次,运行测试并在结束时将其关闭,这还不够吗?
我们也使用Spring,上下文初始化需要时间。
在Junit4之前,我们通过使用布尔标志手动处理它来解决这个限制。
@Before
public void setup() {
if(!containerStarted) {
// start
containerStarted = true;
}
// else do nothing
}
答案 0 :(得分:5)
您可以使用@BeforeClass和@AfterClass来覆盖JerseyTest的@Before和@After生命周期。这是代码模板:
public abstract class MyJerseyTest {
private JerseyTest jerseyTest;
public MyJerseyTest(){
}
@BeforeClass
public void setUp() throws Exception {
initJerseyTest()
jerseyTest.setUp();
}
@AfterClass
public void tearDown() throws Exception {
jerseyTest.tearDown();
}
private void initJerseyTest() {
jerseyTest = new JerseyTest() {
@Override
protected Application configure() {
// do somthing like
enable(...);
set(...);
// create ResourceConfig instance
ResourceConfig rc = new ResourceConfig();
// do somthing like
rc.property(...);
rc.register(...);
return rc;
}
};
}
}
希望这有用。
答案 1 :(得分:2)
我们有类似的情况,使用jersey plus 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
实例中)< / p>
@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块中的一些配置。无论如何,如果你好奇,试一试。
web.xml
上下文init参数,例如applicationContext
。 applicationContext
包含基于弹簧的配置。 ctx
。 server
ResourceConfig
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保证的基本路径设置为
RestAssured.baseURI = "http://localhost:8989/";
如果您不想使用REST保证那么
@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;