📖

Junitでjettyサーバーを起動してServletをテストする

2024/11/17に公開

やりたいこと

テストコードでプログラムからサーバーを起動してServletをテスト実行する

実施目的

サーバー経由じゃないと動かないモジュールのテストコードを書きたいため
スタブやモックライブラリが使えない時の代替案の実現方法を知りたかったため

ビルドファイル

jettyサーバーを起動とテストするServletを登録する必要があるため、build.gradleに以下のライブラリを追加する

testImplementation("org.eclipse.jetty:jetty-server:11.0.15")
testImplementation("org.eclipse.jetty:jetty-servlet:11.0.15")

テストコード

  1. @BeforeAllで実テストを実施する前にサーバーとServletの登録をする
  2. @AfterAllで実テスト後にサーバーをstopさせる
  3. @Testで実テストを実施
    テストしたいクラスはHelloServlet.javaとする
private static Server server;
@BeforeAll
static void startServer() throws Exception {
    server = new Server(8082);
    ServletContextHandler context = new 
    ServletContextHandler(ServletContextHandler.NO_SESSIONS);
    context.setContextPath("/");
    server.setHandler(context);

    // Servletの登録
    context.addServlet(new ServletHolder(new HelloServlet()),"/hello");
    server.start();	
}
@AfterAll
static void stopServer() throws Exception {
    if (server != null && server.isRunning()) {
        server.stop();
    }
}
@Test
void testHelloServlet() throws Exception {
    HttpClient client = HttpClient.newHttpClient();
    HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("http://localhost:8082/hello"))
        .GET()
        .build();
    HttpResponse<String> response = client.send(request, 
         HttpResponse.BodyHandlers.ofString());

    // ステータスコードとレスポンスボディを確認
    assertEquals(200, response.statusCode());
    assertEquals("Hello, Jetty!", response.body());
}

テストしたい実クラス

簡易的なServetクラス
@WebServletでアクセスするパスを設定する

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {		
		res.setContentType("text/plain");
        res.getWriter().write("Hello, Jetty!");
	}
}

はまったこと

アクセスパスを"/"で何も指定しないとServetの返却ステータスコードが302:リダイレクトで返却される
アクセスパスを"/hoge"みたいな感じで指定しないと302で返却される仕様みたい

Discussion