簡體   English   中英

如何在測試類中為所有測試啟動Jersey測試容器(Grizzly)一次?

[英]How to start a Jersey Test Container (Grizzly) once for all tests in a test class?

我正在努力修復其中一個項目中的集成測試。 目前,所有集成測試類都擴展了JerseyTest類。 通過JerseyTest類,我意識到它使用Junit的Before和After注釋為每個測試方法啟動和停止容器。

為什么這有必要? 如果我們提起容器一次,運行測試並在結束時將其關閉,這還不夠嗎?

我們也使用Spring,上下文初始化需要時間。

在Junit4之前,我們通過使用布爾標志手動處理它來解決這個限制。

@Before
public void setup() {
  if(!containerStarted) {
   // start
   containerStarted = true;    
  }
 // else do nothing
}

您可以使用@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;
      }
    };
  }
}

希望這是有幫助的。

我們有類似的情況,使用球衣加彈簧作為依賴注入框架(平針彈簧橋)。 使用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塊中的一些配置。 無論如何,如果你好奇,試一試。

  1. 使用將要測試的資源創建ResourceConfig,這包括您的資源/控制器,ExceptionMapper(如果有),任何其他應該加載的類。
  2. 創建一個WebappContext實例,然后以編程方式向其添加所有web.xml上下文init參數,例如applicationContext applicationContext包含基於spring的配置。
  3. 如果您的web.xml中有一個監聽器,那么您需要以編程方式添加它們,如上所示
  4. 如果您有任何過濾器或其他東西,那么您需要以編程方式將它們添加到ctx
  5. 通過提供URI和ResourceConfig實例,使用Grizzly實例初始化server
  6. 您已經以編程方式創建了一個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保證的基本路徑設置如下

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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM