gpt4 book ai didi

使用 JUnit 进行 JAVA 单元测试最佳实践

转载 作者:行者123 更新时间:2023-12-01 18:11:05 24 4
gpt4 key购买 nike

我目前正在使用以下方法和该方法的单元测试。我认为测试可以/应该分解为更多测试,但我不确定为此编写多少测试,或者更重要的部分是什么,特别是考虑到该方法涉及建立连接,使用 sql 查询等...感谢所有帮助。

JAVA方法:

public static ArrayList<HashMap<String, String>> executeSelect(
Connection conn, Statement stmt, Query query) {

ResultSet rs = null;
ArrayList<HashMap<String, String>> serviceRequests = new ArrayList<HashMap<String, String>>();

try {
long queryStart = System.nanoTime();
rs = stmt.executeQuery(query.getQuery());
long queryEnd = System.nanoTime();
long queryDuration = queryEnd-queryStart;
queryTime = String.valueOf(queryDuration);

while (rs.next()) {

HashMap<String, String> serviceRequestData = new HashMap<>();

if (QueryUtil.hasColumn(rs, "ID")) {
String id = rs.getString("ID");
serviceRequestData.put("ID", id);
}
else{
serviceRequestData.put("ID", " ");
}
if (QueryUtil.hasColumn(rs, "FN_Contact")) {
String firstName = rs.getString("FN_Contact");
serviceRequestData.put("FN_Contact", firstName);
}
else{
serviceRequestData.put("FN_Contact", " ");
}
if (QueryUtil.hasColumn(rs, "LN_Contact")) {
String lastName = rs.getString("LN_Contact");
serviceRequestData.put("LN_Contact", lastName);
}
else{
serviceRequestData.put("LN_Contact", " ");
}
if (QueryUtil.hasColumn(rs, "Notes")) {
String notes = rs.getString("Notes");
serviceRequestData.put("Notes", notes);
}
else{
serviceRequestData.put("Notes", " ");
}
if (QueryUtil.hasColumn(rs, "Email")) {
String email = rs.getString("Email");
serviceRequestData.put("Email", email);
}
else{
serviceRequestData.put("Email", " ");

}

serviceRequests.add(serviceRequestData);

}
} catch (SQLException e) {
e.printStackTrace();
sqlException = true;
}
return serviceRequests;
}

JUnit 测试:

@Test
public void testFirstName() {
ArrayList<HashMap<String, String>> testMap = new ArrayList<HashMap<String,String>>();
Connection conn = null;
Statement stmt = null;
try {
Class.forName("com.mysql.jdbc.Driver");

String connectionUrl = "jdbc:mysql://localhost:3306/gc_image";
String connectionUser = "root";
String connectionPassword = "GCImage";
conn = DriverManager.getConnection(connectionUrl, connectionUser,
connectionPassword);
conn.
stmt = conn.createStatement();
Query testQuery = new Query();
testQuery
.setQuery("select * from service_request where FN_contact = 'Trevor'");
testMap = QueryController.executeSelect(conn, stmt, testQuery);

assertEquals("Janke", testMap.get(0).get("LN_Contact"));
assertEquals("Hello World", testMap.get(0).get("Notes"));
assertEquals("janke@gmail.com", testMap.get(0).get("Email"));
assertEquals("ID", testMap.get(0).get("7"));

} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
stmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}

}

最佳答案

您应该首先确定该测试设置的哪些部分并不是测试方法的真正一部分;即,可以提取到 @Before 中的样板是什么?和@After方法。这可能需要您将一些局部变量放入类变量中。这使得每个@Test方法不太冗长,可以让您专注于测试中的功能。

接下来您应该删除所有 catch阻止,或者测试失败,如 fail(exception.getMessage())如果您的代码或测试代码引发意外异常。如果删除它们,很容易将单元测试的方法签名更改为 throws Exception如果抛出异常,则允许它通常失败。就像现在一样,您可能完全无法连接到设置中的数据库,并且 Junit 测试仍然会变绿!

理想情况下,您应该有一个涵盖每个 if...else 的单元测试。堵塞。这会给你 10 次测试。其中,重点( Assert )是确认 serviceRequests 中是否存在找到/未找到的值。 。您还应该测试异常处理,因此您需要一个强制 SQLException 的测试。被捕获。

我最后建议,为了减少开销,您可以考虑使用模拟框架,例如 Mockito完全消除数据库 I/O。这个SO question有一些模拟数据库的好例子。

我在 executeSelect() 中注意到了一些快速的事情可以修复的:

  • 删除 Connection一个参数——它没有被使用,如 Statement已经实例化了。
  • 考虑抛出 SQLException 而不是返回 List - 它会给出一个错误的广告,表明数据库读取已成功执行。
  • 优先选择接口(interface)和抽象类而不是具体类:更改方法签名和 serviceRequests来自ArrayList<HashMap<String, String>>List<Map<String, String>> 。在众多资源中,Josh Bloch 的 Effective Java对于这个主题来说是一个很好的引用。

您可以通过将以下代码移动到另一个方法中来进一步简化此方法,这将使测试更加简单:

    long queryStart = System.nanoTime();
rs = stmt.executeQuery(query.getQuery());
long queryEnd = System.nanoTime();
long queryDuration = queryEnd-queryStart;
queryTime = String.valueOf(queryDuration);

然后只传递 ResultSet进入executeSelect() ...或者将其重命名为任何名称:)。

关于使用 JUnit 进行 JAVA 单元测试最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32899738/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com