我正在开发一个项目,我们需要创建一些测试用例。我有一个 SQL 数据库并使用如下查询解析数据:
public Contractor create(String name, String address, String email, String phone, String city, int cvr) throws SQLException{
Contractor contractor = new Contractor(name, address, email, phone, city, cvr);
String sql = String.format("INSERT INTO person (name, address, email, phone, city, category) VALUES ('%s', '%s', '%s', '%s', '%s', 2)", name, address, email, phone, city);
try{
Connection conn = DBConnection.getInstance().getDBcon();
conn.createStatement().executeUpdate(sql);
String sql2 = "SELECT TOP 1 id FROM Person ORDER BY id DESC";
ResultSet rs = conn.createStatement().executeQuery(sql2);
if(rs.next()) {
String sql3 = "INSERT INTO contractor (cvr, person_id) VALUES (2666,"+rs.getInt("id")+")";
conn.createStatement().executeUpdate(sql3);
}else{
throw new SQLException();
}
} catch (SQLException e){
e.printStackTrace();
} finally {
DBConnection.closeConnection();
}
return contractor;
}
使用 JUnit 进行的测试会是什么样子?
最佳答案
嗯,Junit 的使用方式必须是通过测试类的每个公共(public)方法,并根据实验成功或失败的数量使用尽可能多的不同参数。
每种测试方法都必须:
- 选择一组合适的参数值。
- (可选)将测试组件初始化为所需的初始状态。
- 调用测试方法。
- 检查返回结果是否等于预期结果。
- 清理被测试的组件,不要让执行的测试留下任何“污垢”。
在您的情况下,检查结果很困难,因为连接是由您的方法在本地管理的。更糟糕的是:数据会自动提交到连接中,从而在每次测试时在数据库中留下脏记录。
为了避免这种困难,之前进行一些重构就足以简化测试开发:
- 在类中重载方法
create
,具有包访问版本,该版本还接收连接,并将所有业务逻辑放在那里。 - 公共(public)重载应仅管理连接并调用新创建的重载。
然后,您就可以安全地进行测试了:
- 如果您的类(class)名为
MyClass
,创建一个MyClassTest
在同一个包中(通常在不同的源路径中,例如 Maven 项目中的src\test\java
)。 - 创建一个方法
createSinglePerson()
它调用create
具有任意一组参数和一个连接(非自动提交)。之后,您必须检查 Person 表中是否比最初多了一条具有一组特定值的记录,以及 Contractor 表中是否多了一条具有某些值集。要比较每个值,您必须使用Asserts.assertEquals(expected, real)
。最后(在finally子句中),回滚连接并关闭它。
您可以根据需要多次运行测试,并且知道它不会改变数据库状态。
(注意:参数 cvr
从未使用过。也许你是故意这样做的,我不知道)。
示例
public class MyClassTest
{
@Test
public void createSinglePerson()
{
MyClass myClass=new MyClass();
try(Connection connection=...)
{
try(Statement stCheck=connection.createStatement())
{
connection.setAutoCommit(false);
// Initial cleanup:
stCheck.executeUpdate("DELETE FROM person");
stCheck.executeUpdate("DELETE FROM contractor");
// Setting input parameters:
String name="a";
String address="b";
String email="c@d.e";
String phone="001";
String city="f";
int cvr=11;
// Do the call:
Contractor contractor=myClass.create(name, address, email, phone, city, cvr);
// Javabean Checks: Check the javabean contains the expected values:
assertEquals(name, contractor.getName());
assertEquals(address, contractor.getAddress());
...
// Database Checks:
int personId;
// Check the Person table contains one row with the expected values:
try(ResultSet rs=stCheck.executeQuery("SELECT * FROM person"))
{
assertTrue(rs.next());
personId=rs.getInt("id");
asssertEquals(name, rs.getString("name"));
asssertEquals(address, rs.getString("address"));
...
assertFalse(rs.next());
}
// Check the Contractor table contains one row with the expected values:
try(ResultSet rs=stCheck.executeQuery("SELECT * FROM contractor WHERE person_id="+personId))
{
assertTrue(rs.next());
asssertEquals(2666, rs.getInt("cvr"));
...
assertFalse(rs.next());
}
}
finally
{
// Undo the testing operations:
connection.rollback();
}
}
catch (SQLException e)
{
fail(e.toString());
}
}
}
关于java - JUnit 测试 SQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61175741/