在Java測試堆棧上打造您的瑞士軍刀

程式碼的可測試性確保了高效程式碼設計中的數個優點,例如可維護性;它有助於文件編制,並使得重構和建立演進式設計/架構更加容易。這點毫無疑問,但一個好的測試棧應該如何開始一個專案呢?本影片將解釋使用Java啟動專案所需的最低測試棧。

當我們談論最低限度時,首先要明白的是,測試棧中沒有萬能的解決方案。最終,我們需要包含或移除依賴,特別是在討論舊有程式碼時。基於這一點,我將分享我最喜歡的Java測試棧,並將其作為從零開始的最低建議:

  • JUnit-Jupiter:JUnit的第五版與前一版不兼容;然而,它帶來了許多功能,主要是用於創建自定義擴展,這非常值得。

  • Mockito:一個在Java中極為流行的模擬框架。其受歡迎程度和龐大的社群支持了許多擴展,例如與JUnit-Jupiter的結合。

  • AssertJ: 如果你和我一樣喜愛流暢的API,那麼AssertJ對你來說是一個非常出色的庫。

使用maven項目,你可以添加這些庫的依賴:

XML

 

<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進行的測試,在這裡我們不需要數據庫,也不需要偏離焦點去測試業務。

Java

 

@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,使得斷言更易於理解。您可以測試集合、地圖或單一實例。例如,我們可以利用它來驗證將一名玩家加入團隊的情況。

Java

 

@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