避免 JUnit 中的「無可運作方法」錯誤
1. 概述
JUnit 是 Java 單元測試的主要選擇。在測試執行過程中,開發人員經常會遇到一個奇怪的錯誤,即即使我們導入了正確的類,也沒有可運行的方法。
在本教程中,我們將看到導致此錯誤的一些特定情況以及如何修復它們。
2.缺少@Test
註解
首先,測試引擎必須識別測試類別才能執行測試。如果沒有有效的測試可以運行,我們會得到一個異常:
java.lang.Exception: No runnable methods
為了避免這種情況,我們需要確保測試類別始終使用 JUnit 庫中的@Test
註解進行註解。
對於 JUnit 4.x,我們應該使用:
import org.junit.Test;
另一方面,如果我們的測試庫是 JUnit 5.x,我們應該從 JUnit Jupiter 匯入套件:
import org.junit.jupiter.api.Test;
另外,我們要特別注意TestNG框架的@Test
註解:
import org.testng.annotations.Test;
當我們匯入此類來取代 JUnit 的@Test
註解時,可能會導致「無可運行方法」錯誤。
3. 混合 JUnit 4 和 JUnit 5
某些舊專案的類別路徑中可能同時具有 JUnit 4 和 JUnit 5 程式庫。雖然當我們混合使用兩個函式庫時編譯器不會報告任何錯誤,但在執行 JUnit 時我們可能會遇到「無可運行方法」錯誤。我們來看一些案例。
3.1.錯誤的 JUnit 4 導入
發生這種情況主要是由於 IDE 的自動匯入功能會匯入第一個符合的類別。讓我們看看正確的 JUnit 4 導入:
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
如上所示,我們可以注意到org.junit
套件包含 JUnit 4 的核心類別。
3.2.錯誤的 JUnit 5 導入
同樣,我們可能會錯誤地導入 JUnit 4 類別而不是 JUnit 5,並且測試將無法運行。因此,我們需要確保為 JUnit 5 導入正確的類別:
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
在這裡,我們可以看到JUnit 5的核心類別屬於org.junit.jupiter.api
套件。
3.3. @RunWith
和@ExtendWith
註解
對於使用Spring框架的項目,我們需要導入一個特殊的註解來進行整合測試。對於 JUnit 4,我們使用@RunWith
註解來載入 Spring TestContext 框架。
然而,對於在 JUnit 5 上編寫的測試,我們應該使用@ExtendWith
註解來獲得相同的行為。當我們將這兩個註釋與不同的 JUnit 版本互換時,測試引擎可能找不到這些測試。
此外,要對基於 Spring Boot 的應用程式執行 JUnit 5 測試,我們可以使用[@SpringBootTest](https://docs.spring.io/spring-boot/api/java/org/springframework/boot/test/context/SpringBootTest.html)
註釋,該註釋在@ExtendWith
註釋之上提供附加功能。
4. 測試實用程式類
當我們想要在不同的類別中重複使用相同的程式碼時,實用程式類別非常有用。因此,測試實用程式類別或父類別共用一些公共設定或初始化方法。由於類別命名,測試引擎將這些類別識別為真正的測試類,並嘗試找到可測試的方法。
讓我們來看看實用程式類別:
public class NameUtilTest {
public String formatName(String name) {
return (name == null) ? name : name.replace("$", "_");
}
}
在這種情況下,我們可以觀察到NameUtilTest
類別與真實測試類別的命名約定相符。但是,沒有用@Test
註釋的方法,這會導致“無可運行的方法”錯誤。為了避免這種情況,我們可以重新考慮這些實用程式類別的命名。
因此,以「 *Test
」結尾的實用程式類別可以重新命名為「* TestHelper
」或類似名稱:
public class NameUtilTestHelper {
public String formatName(String name) {
return (name == null) ? name : name.replace("$", "_");
}
}
或者,我們可以為以「 Test
」模式結尾的父類別指定abstract
修飾符(例如, BaseTest
),以防止該類別執行測試。
5. 明確忽略的測試
雖然不是常見情況,但有時所有測試方法或整個測試類別都可能被錯誤地標記為可跳過。
@Ignore
(JUnit 4) 和@Disabled
(JUnit 5) 註釋對於暫時阻止某些測試運行非常有用。當測試修復很複雜或我們需要緊急部署時,這可能是使建置回到正軌的快速修復:
public class JUnit4IgnoreUnitTest {
@Ignore
@Test
public void whenMethodIsIgnored_thenTestsDoNotRun() {
Assert.assertTrue(true);
}
}
在上面的例子中,封閉的JUnit4IgnoreUnitTest
類別只有一個方法,並且被標記為@Ignore
。當我們使用 IDE 或 Maven 建置執行測試時,這可能會導致「無可運行方法」錯誤,因為Test
類別沒有可測試的方法。
為了避免此錯誤,最好刪除@Ignore
註釋或至少有一個有效的測試方法可供執行。
六、結論
在本文中,我們了解了在 JUnit 中執行測試時出現「無可運行方法」錯誤的幾種情況,以及如何修復每種情況。
首先,我們看到缺少正確的@Test
註釋可能會導致此錯誤。其次,我們了解到混合 JUnit 4 和 JUnit 5 中的類別可能會導致相同的情況。我們也觀察了命名測試實用程式類別的最佳方式。最後,我們討論了明確忽略的測試以及它們如何成為一個問題。
與往常一樣,本文中提供的程式碼可以在 GitHub 上取得。