2016-09-15 3 views
2

MySQLデータベースからResultSetを取得しようとしていて、クラスのパブリックメソッド(search & add)のJUnitテストを作成したいと考えています。データベースクエリのJUNITテストへのアプローチ

データベース関連のクラスのJUnitテストを書く方法はどれですか?

public class MetropolisModel implements MetropolisControl { 

    private int rowsCount = 0; 
    private int columesCount = 0; 
    private ResultSet lastResult = null; 

    @Override 
    public ResultSet search(String metropolis, String continent, String population, boolean populationLargerThan, boolean exactMatch) { 
     ResultSet rs = null; 

     try { 

      Connection c = MyDB.getConnection(); 
      String query = createSearchQuery(metropolis, continent, population, populationLargerThan, exactMatch); 

      PreparedStatement ps = c.prepareStatement(query); 

      int position = 1; 

      if (!metropolis.isEmpty()) { 
       ps.setString(position, addPercentageSign(metropolis, exactMatch)); 
       position++; 
      } 
      if (!continent.isEmpty()) { 
       ps.setString(position, addPercentageSign(continent, exactMatch)); 
       position++; 
      } 
      if (!population.isEmpty()) { 
       ps.setString(position, population); 
      } 

      rs = ps.executeQuery(); 

      setTable(rs); 

      System.out.println("after " + ps + "%nFound records: " + rowsCount); 

     } catch (SQLException e) { 
      e.printStackTrace(); 
     } 

     return rs; 

    } 

    @Override 
    public void add(String metropolis, String continent, String population) { 

     try { 

      Connection c = MyDB.getConnection(); 

      String query = "insert into metropolises values(?,?,?);"; 

      PreparedStatement ps = c.prepareStatement(query); 

      ps.setString(1, metropolis); 
      ps.setString(2, continent); 

      if (population.isEmpty()) { 
       ps.setNull(3, Types.BIGINT); 
      } else { 
       ps.setString(3, population); 
      } 

      ps.executeUpdate(); 

      search(metropolis, continent, population, true, true); 

     } catch (SQLException ex) { 
      ex.printStackTrace(); 
     } 
    } 

    private String createSearchQuery(String metropolis, String continent, String population, boolean populationLargerThan, boolean exactMatch) { 
     String query = "select * from metropolises"; 

     if (!metropolis.isEmpty() || !continent.isEmpty() || !population.isEmpty()) { 
      query += " where "; 
      String operatorForString = exactMatch ? " = " : " like "; 
      String operatorForInt = exactMatch ? " = " : populationLargerThan ? " > " : " < "; 

      query += metropolis.isEmpty() ? "" : " metropolis " + operatorForString + " ?"; 
      query += continent.isEmpty() ? "" : addANDKeyword(" continent " + operatorForString + " ? ", !metropolis.isEmpty()); 
      query += population.isEmpty() ? "" : addANDKeyword(" population " + operatorForInt + " ? ", !metropolis.isEmpty() || !continent.isEmpty()); 
     } 

     query += ";"; 
     System.out.println(query); 
     return query; 
    } 

    private String addANDKeyword(String input, boolean needToAddKeyword) { 
     if (!needToAddKeyword) { 
      return input; 
     } else { 
      input = " and " + input; 
      return input; 
     } 
    } 

    private String addPercentageSign(String input, boolean exactMatch) { 
     if (exactMatch) { 
      return input; 
     } else { 
      return "%" + input + "%"; 
     } 
    } 

    private void setTable(ResultSet rs) throws SQLException { 
     lastResult = rs; 
     ResultSetMetaData rsmd = rs.getMetaData(); 
     columesCount = rsmd.getColumnCount(); 
     rs.last(); 
     rowsCount = rs.getRow(); 
    } 
} 

答えて

2
  1. 速度に対するHSQLDBのメモリ内インスタンスを使用。 (使用しているデータベースの構文は、HSQLDBの構文とは多少異なる可能性があるため、データベースアクセスの仕組みによってデータベース構文の違いを気にする必要がない場合は、もちろん可能です)
  2. テストクラスは、スキーマを作成し、サンプルデータをデータベースに取り込むことから始まります。
  3. 各テストクラスは、データベーススキーマ名としてドットをアンダースコアに置き換えた後に独自のフルネーム(getClass()。getName()を使用する)を使用して、あるテストが別のテストのスキーマを混乱させないようにします。
  4. 各試験方法は、以下のん:
    1. がトランザクション
    2. は、おそらくより多くのサンプルデータ
    3. を追加開始すると、クエリ
    4. が結果
    5. を期待通りの結果があることを確認受け取り行います
    6. トランザクションをロールバックするので、各テストメソッドは、データベースを見つけたときとまったく同じ状態にします。