Java 用JUnit测试一个方法

Java 用JUnit测试一个方法,java,testing,junit,Java,Testing,Junit,如何测试此方法: public void updateTable() { try { String sql = "select * from userDetails"; rs = st.executeQuery(sql); st = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);

如何测试此方法:

public void updateTable() {                 
    try {
        String sql = "select * from userDetails";
        rs = st.executeQuery(sql);
        st = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
        table.setModel(DbUtils.resultSetToTableModel(rs));  
    }
    catch(Exception e) {
    }

没有什么建议可以让这更易于测试

updateTable
方法在这里做两件事

  • 执行查询并获取结果
  • 将结果集应用于表
  • 我会重构两种方法

  • public ResultSet getResultSetForQuery(字符串sql,语句st)
  • 公共表更新表(ResultSet rs)

  • 为上述两种方法编写测试应该很简单。

    任何好的测试的两个要点是:

  • 检查它是否工作正常
  • 如果存在错误,则将其本地化
  • 检查它是否工作正常 如果存在错误,则将其本地化 在您的情况下,如果存在错误,我们无法执行这样好的测试来定位错误,因为您的方法太复杂了。最好将您的方法重构为几个方法,使其更具可读性和可测试性。我同意@AjayGeorge关于分离该方法的方法

    然后你可以写一些东西,比如:

    import org.junit.AfterClass;
    import org.junit.BeforeClass;
    import org.junit.Test;
    
    import java.sql.ResultSet;
    
    public class TestExample {
    
        @BeforeClass
        public static void setup() {
            // init your connection here
            // and insert data for tests
        }
    
        @AfterClass
        public static void cleanup() {
            // close connection
        }
    
        @Test
        public void testTableUpdate() {
    
            // initialize 'sqlQuery' and 'statement'
    
            ResultSet resultSet = getResultSetForQuery(sqlQuery, statement);
    
            // check 'resultSet' with JUnit methods like assertTrue
    
            updateTable(resultSet);
    
            // check that table is filled as you expected
        }
    
    }
    

    有很多java库可用于模拟大数据,以帮助测试与数据库相关的方法。例如Mockito//等。您可以利用这些库。您可以使用这些工具模拟预期结果,并且可以使用预期结果测试您的方法

    JUnit:一般来说,您编写一个测试类,如下所示,并用@test注释包含您的测试的方法。如果要编写一个必须失败的测试,可以使用注释的“expected”属性。如果您知道您的测试可能运行的时间太长,并且希望它在一段时间后超时,请在注释中使用“timeout”属性

    如果在每个测试方法之前都有特定的初始化逻辑,那么可以将其放入另一个方法中,并用@before注释该方法。同样,要释放内容,可以使用@After。对于每个测试类运行一次的初始化,请使用注释@BeforeClass并确保该方法是公共的和静态的-与@AfterClass的情况相同

    一般来说,在每个测试方法中,您都是这样做的:执行一些代码,然后对预期的情况做出断言。在我的示例中,我正在测试“myAdd”方法,我希望1+1加起来等于2

    public class MyTest {
      @Test
      public void testAddition() {
        int sum = myAdd(1, 1);
        assertEquals(2, sum);
      }
    }
    
    此示例基于JUnit: 还有其他选择,如TestNG:


    如果您想测试某个类相对于其depdencies的行为,建议使用模拟框架。示例包括:jmock、mockito等

    在实例化语句后执行查询,而不吃异常。像这样的
    公共结果集getResultSetForQuery(String sql,statement st)
    方法是否太原子化,无法测试执行像
    “select*from userDetails”这样的查询?取决于为其编写测试是否会增加价值。那个测试会做什么?测试您的模式?或者测试你的DB驱动程序。@Khalladshahin那么这将是一个错误的选择。我确信你的db驱动程序经过了很好的测试。这应该是集成测试的一部分,而不是单元测试,因为它不测试任何逻辑。在设置时,我会擦除表并插入条目。这样,您将始终使用相同的数据集进行测试