Servletクラスのテスト
目的
JSONを返却するServletクラスの単体テストがしたい。
概要
- GETメソッドのサーブレット
- doGetをたたく
- 引数にはMockHttpServletRequest, MockHttpServletResponseを利用
- Connectionはデータソースを利用
- PowerMockでモック
- JUnitのTheoryも併用
- PowerMockでモック
検証プログラム
概要
- idを渡して該当するレコードの内容をJSON形式で返却する
- 該当idがない場合は空オブジェクトを返却する
- DBデータ(テーブル:voiceact)
uid | uname | age | office |
---|---|---|---|
aimi | 愛美 | 26 | 響 |
goto | 後藤沙緒里 | 31 | null |
ソース
サーブレット
package kurukuruz.sample.servlet; import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import kurukuruz.sample.servlet.connection.ConnectionPool; import kurukuruz.sample.servlet.util.User; import net.arnx.jsonic.JSON; /** * Servlet implementation class Search */ @WebServlet(name = "search", urlPatterns = { "/search" }) public class Search extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // パラメータ取得 String id = request.getParameter("id"); // 検索実行 User user = searchById(id); // JSON作成 String result = "{}"; if(user != null){ result = JSON.encode(user); } // 返却 response.setContentType("application/json"); response.setCharacterEncoding("UTF-8"); PrintWriter pw = response.getWriter(); pw.print(result); } private User searchById(String id){ User user = null; Connection conn = null; PreparedStatement ps = null; try { conn = ConnectionPool.getConnection(); String sql = "SELECT uname, age, office " + "FROM voiceact " + "WHERE uid = ?"; ps = conn.prepareStatement(sql); ps.setString(1, id); ResultSet rs = ps.executeQuery(); if(rs.next()){ user = new User(rs.getString(1), rs.getInt(2), rs.getString(3)); } } catch (SQLException e) { throw new RuntimeException(e); } finally { if(ps != null){ try { ps.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn != null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } return user; } }
テストクラス
package kurukuruz.sample.servlet; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; import java.io.IOException; import java.math.BigDecimal; import java.util.Map; import javax.servlet.ServletException; import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; import lombok.Setter; import kurukuruz.sample.servlet.connection.ConnectionPool; import kurukuruz.sample.servlet.testbase.ServletTestBase; import net.arnx.jsonic.JSON; import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.theories.DataPoints; import org.junit.experimental.theories.Theories; import org.junit.experimental.theories.Theory; import org.junit.runner.RunWith; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import org.powermock.modules.junit4.PowerMockRunnerDelegate; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; @RunWith(PowerMockRunner.class) @PowerMockRunnerDelegate(Theories.class) @PrepareForTest({ConnectionPool.class}) public class SearchTest extends ServletTestBase { @DataPoints public static final Fixture[] fixtures = { new Fixture("aimi", "愛美", new BigDecimal(26), "響", false), new Fixture("goto", "後藤沙緒里", new BigDecimal(31), null, false), new Fixture("ayasa", null, null, null, true), new Fixture("", null, null, null, true), new Fixture(null, null, null, null, true), }; @Theory @Test public void test(Fixture fixture) throws ServletException, IOException { MockHttpServletRequest req = new MockHttpServletRequest(); MockHttpServletResponse res = new MockHttpServletResponse(); req.setParameter("id", fixture.id); Search target = new Search(); target.doGet(req, res); @SuppressWarnings("rawtypes") Map result = JSON.decode(res.getContentAsString()); if(fixture.isEmpty){ assertTrue("Mapの空判定", result.isEmpty()); }else{ assertThat("name判定", result.get("name"), is(fixture.name)); assertThat("age判定", result.get("age"), is(fixture.age)); assertThat("pc判定", result.get("pc"), is(fixture.pc)); } } @Ignore @NoArgsConstructor @AllArgsConstructor @Setter public static class Fixture { // 検索条件 private String id; // 想定結果 private String name; private BigDecimal age; private String pc; private boolean isEmpty; } }
テストベースクラス
package kurukuruz.sample.servlet.testbase; import static org.mockito.Mockito.*; import java.sql.Connection; import java.sql.DriverManager; import kurukuruz.sample.servlet.connection.ConnectionPool; import org.junit.Before; import org.junit.BeforeClass; import org.powermock.api.mockito.PowerMockito; public class ServletTestBase { protected static Connection Conn; @BeforeClass public static void setupBeforeClass() throws Exception { Class.forName("org.postgresql.Driver"); } @Before public void setup() throws Exception { Conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/test", "user", "pass"); PowerMockito.mockStatic(ConnectionPool.class); when(ConnectionPool.getConnection()).thenReturn(Conn); } }