2016-09-15 30 views
2

我试图从MySQL数据库中检索一些ResultSet,并且希望为我的类的公共方法编写JUnit测试(search & add)。如何处理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. ROLLS返回事务,因此每个测试方法都会像发现它一样离开数据库。