程式碼的可測試性確保了高效程式碼設計中的數個優點,例如可維護性;它有助於文件編制,並使得重構和建立演進式設計/架構更加容易。這點毫無疑問,但一個好的測試棧應該如何開始一個專案呢?本影片將解釋使用Java啟動專案所需的最低測試棧。
當我們談論最低限度時,首先要明白的是,測試棧中沒有萬能的解決方案。最終,我們需要包含或移除依賴,特別是在討論舊有程式碼時。基於這一點,我將分享我最喜歡的Java測試棧,並將其作為從零開始的最低建議:
-
JUnit-Jupiter:JUnit的第五版與前一版不兼容;然而,它帶來了許多功能,主要是用於創建自定義擴展,這非常值得。
-
Mockito:一個在Java中極為流行的模擬框架。其受歡迎程度和龐大的社群支持了許多擴展,例如與JUnit-Jupiter的結合。
-
AssertJ: 如果你和我一樣喜愛流暢的API,那麼AssertJ對你來說是一個非常出色的庫。
使用maven項目,你可以添加這些庫的依賴:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.verson}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>${mockito.verson}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.verson}</version>
<scope>test</scope>
</dependency>
假設在一個足球冠軍聯賽的背景下,我們有一支隊伍,該隊伍應該有十一個球員,每個球員的名字在聯賽中必須是唯一的。我們可以對此進行測試。
從JMockito和測試開始,我們需要測試一個服務,該服務需要檢查名字是否存在於數據庫中以進行邏輯處理。在這一點上,我們不需要也不想創建一個集成測試。
我們希望專注於業務,因此不想測試數據庫或框架,只測試我們的代碼。因此,我們將使用兩種場景來模擬倉庫:當名字存在和當名字不存在。
使用Mockito與JUnit-Jupiter的集成,你可以僅通過註解注入模擬對象。下面的代碼展示了使用JMockito進行的測試,在這裡我們不需要數據庫,也不需要偏離焦點去測試業務。
@ExtendWith(MockitoExtension.class)
class ChampionshipServiceTest {
@Mock
private ChampionRepository repository;
@InjectMocks
private ChampionshipService service;
@Test
public void shouldRegister() {
Mockito.when(repository.existByName("Bahia")).thenReturn(false);
Team bahia = Team.of("Bahia");
service.register(bahia);
Mockito.verify(repository).existByName("Bahia");
}
@Test
@DisplayName("should return an exception when there is a team with a name")
public void shouldThrownAnExceptionWhenTeamNameExists() {
Mockito.when(repository.existByName("Bahia")).thenReturn(true);
Team bahia = Team.of("Bahia");
Assertions.assertThrows(IllegalArgumentException.class, () ->
service.register(bahia));
Mockito.verify(repository).existByName("Bahia");
}
}
AssertJ 透過其支援的流暢 API,使得斷言更易於理解。您可以測試集合、地圖或單一實例。例如,我們可以利用它來驗證將一名玩家加入團隊的情況。
@Test
public void shouldCreatePlayers() {
Team bahia = Team.of("Bahia");
bahia.add(Player.of("Neymar", "Santos", 10));
bahia.add(Player.of("Cristiano Ronaldo", "Lisbon", 10));
org.assertj.core.api.Assertions.assertThat(bahia.players())
.hasSize(2)
.map(Player::name)
.contains("Neymar", "Cristiano Ronaldo");
}
欲了解更多資訊,請觀看此影片。
重點摘要:
-
A minimum test stack to start Java
-
深入了解 JUnit 及其為何是優選
-
透過 JMockito 探索模擬對象
-
使用流暢 API 斷言——AssertJ,讓您的測試更美觀
Source:
https://dzone.com/articles/creating-your-swiss-army-knife-on-java-test-stack