JavaRush /Java Blog /Random-TW /JUnit 第一部分

JUnit 第一部分

在 Random-TW 群組發布

JUnit :: 或如何喜歡 JavaRush 驗證器

JUnit 第一部分 - 1簡要說明為什麼我們需要這個野獸?JUnit是一個用來自動測試好程式碼或不太好程式碼的框架。你可以說: - 為什麼我需要這個 swing,我可以輕鬆簡單地測試我好的 Java 程式碼。你可以寫很多介紹性的歌詞,但我不是什麼詩人,咱們言歸正傳吧…

創建一個對象

因此,為了測試某些東西,我們首先需要一個測試物件。我們面前有一項任務。
  1. 我們需要一個物件來儲存有關用戶的信息。
    1. Id - 必須按照新增使用者的順序進行計數。
    2. 使用者名稱.
    3. 他的年齡。
    4. 性別(男/女)
  2. 有必要提供用戶清單的儲存。

  3. 班級一定可以。

    1. 產生所有使用者的列表。
    2. 按性別(男性/女性)產生使用者清單。
    3. 傳回總列表中使用者的數量,並根據使用者的性別計算數量。
    4. 以使用者年齡計算總金額,並考慮性別。
    5. 計算總體平均年齡和按性別劃分的平均年齡。
那麼,讓我們開始建立一個物件...讓我們建立一個User包含欄位的 Java 類別:
private int id;
private String name;
private int age;
private Sex sex;
這足以儲存用戶數據,讓我們看看該任務還需要什麼。我們需要以某種方式儲存所有用戶,讓我們在我們的類別中建立一個靜態字段allUsers,我認為如果是的話可以Map<Integer, User>
private static Map<Integer, User> allUsers;
我們還需要以某種方式為用戶分配一個序號,讓我們建立一個靜態計數器字段,當創建新用戶時,它將Id 為該用戶分配一個序號。
private static int countId = 0;
所以,我們似乎已經整理好了字段,讓我們為我們的物件編寫一個建構函數,並為字段id, name, age,編寫 getter sex。heterae 沒什麼複雜的,我們向IDEA尋求幫助吧,她永遠不會拒絕,我們會讓建構子變得有點棘手。設計師一定能夠做到。初始化字段,檢查 中是否有這樣的對象allUsers,如果沒有這樣的對象,則增加我們的計數器countId++並將其添加到所有用戶的列表中。allUsers 如果該欄位尚未初始化,則也要初始化該欄位。為了方便搜尋相同的對象,我們將重新定義方法,equals()並且再次向我們心愛的IDEAhashCode()尋求幫助並按字段進行比較,,。另外,讓我們建立一個私有方法來檢查這樣的物件是否在列表中。 nameagesexhasUser()
@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    User user = (User) o;
    return age == user.age &&
            Objects.equals(name, user.name) &&
            sex == user.sex;
}

@Override
public int hashCode() {

    return Objects.hash(name, age, sex);
}
最後,我遇到了這樣的設計師。
public User(String name, int age, Sex sex) {
    if (allUsers == null){
        allUsers = new HashMap<>();
    }

    this.name = name;
    this.age = age;
    this.sex = sex;

    if (!hasUser()){
        countId++;
        this.id = countId;
        allUsers.put(id, this);
    }
}
和一個私人輔助方法
private boolean hasUser(){
    for (User user : allUsers.values()){
        if (user.equals(this) && user.hashCode() == this.hashCode()){
            return true;
        }
    }
    return false;
}
並且也重新定義toString()
@Override
public String toString() {
    return "User{" +
            "id=" + id +
            ", name='" + name + '\'' +
            ", age=" + age +
            ", sex=" + sex +
            '}';
}
現在是時候實作所需方法的邏輯了。由於邏輯主要使用靜態字段,因此我們也將方法設為靜態;物件不需要它們。
  1. 產生所有使用者的列表。
  2. 按性別(男性/女性)產生使用者清單。
  3. abgetAllUsers()可以透過傳回 all 列表的方法和傳回列表的User重載方法來很好地處理,具體取決於傳遞的參數。getAllUsers(Sex sex)Sex

    public static List<User> getAllUsers(){
        return new ArrayList<>(allUsers.values());
    }
    
    public static List<User> getAllUsers(Sex sex){
        List<User> listAllUsers = new ArrayList<>();
        for (User user : allUsers.values()){
            if (user.sex == sex){
                listAllUsers.add(user);
            }
        }
        return listAllUsers;
    }

  4. 傳回總列表中使用者的數量,並根據使用者的性別計算數量。

    public static int getHowManyUsers(){
        return allUsers.size();
    }
    
    public static int getHowManyUsers(Sex sex){
        return getAllUsers(sex).size();
    }

  5. 以使用者年齡計算總金額,並考慮性別。讓我們為此任務創建方法。

    public static int getAllAgeUsers(){
        int countAge = 0;
        for (User user : allUsers.values()){
            countAge += user.age;
        }
        return countAge;
    }
    
    public static int getAllAgeUsers(Sex sex){
        int countAge = 0;
        for (User user : getAllUsers(sex)){
            countAge += user.age;
        }
        return countAge;
    }

  6. 計算總體平均年齡和按性別劃分的平均年齡。

    public static int getAverageAgeOfAllUsers(){
        return getAllAgeUsers() / getHowManyUsers();
    }
    
    public static int getAverageAgeOfAllUsers(Sex sex){
        return getAllAgeUsers(sex) / getHowManyUsers(sex);
    }

    太好了,我們已經描述了所需的物件及其行為。現在我們可以繼續使用JUnit ,但首先我將向您展示如果我們在main中進行簡單測試會是什麼樣子。

    public static void main(String[] args) {
        new User("Eugene", 35, Sex.MALE);
        new User("Marina", 34, Sex.FEMALE);
        new User("Alina", 7, Sex.FEMALE);
    
    
        System.out.println("All users:");
        User.getAllUsers().forEach(System.out::println);
        System.out.println("All users: MALE");
        User.getAllUsers(Sex.MALE).forEach(System.out::println);
        System.out.println("All users: FEMALE");
        User.getAllUsers(Sex.FEMALE).forEach(System.out::println);
        System.out.println("================================================");
        System.out.println(" all users: " + User.getHowManyUsers());
        System.out.println(" all MALE users: " + User.getHowManyUsers(Sex.MALE));
        System.out.println("all FEMALE users: " + User.getHowManyUsers(Sex.FEMALE));
        System.out.println("================================================");
        System.out.println(" total age of all users: " + User.getAllAgeUsers());
        System.out.println(" total age of all MALE users: " + User.getAllAgeUsers(Sex.MALE));
        System.out.println("total age of all FEMALE users: " + User.getAllAgeUsers(Sex.FEMALE));
        System.out.println("================================================");
        System.out.println(" average age of all users: " + User.getAverageAgeOfAllUsers());
        System.out.println(" average age of all MALE users: " + User.getAverageAgeOfAllUsers(Sex.MALE));
        System.out.println("average age of all FEMALE users: " + User.getAverageAgeOfAllUsers(Sex.FEMALE));
        System.out.println("================================================");
    }

    控制台的輸出看起來像這樣,然後我們將比較是否正常運作。當然,我們可以更深入地編寫比較邏輯,並查看我們的計算結果,即使我們不確定我們是否能夠提供所有內容。

    //output
    Все пользователи:
    User{id=1, name='Eugene', age=35, sex=MALE}
    User{id=2, name='Marina', age=34, sex=FEMALE}
    User{id=3, name='Alina', age=7, sex=FEMALE}
    Все пользователи: MALE
    User{id=1, name='Eugene', age=35, sex=MALE}
    Все пользователи: FEMALE
    User{id=2, name='Marina', age=34, sex=FEMALE}
    User{id=3, name='Alina', age=7, sex=FEMALE}
    ================================================
           всех пользователей: 3
      всех пользователей MALE: 1
    всех пользователей FEMALE: 2
    ================================================
           общий возраст всех пользователей: 76
      общий возраст всех пользователей MALE: 35
    общий возраст всех пользователей FEMALE: 41
    ================================================
           средний возраст всех пользователей: 25
      средний возраст всех пользователей MALE: 35
    средний возраст всех пользователей FEMALE: 20
    ================================================
    
    Process finished with exit code 0

    我們對這個結果並不滿意,在主要測試結束後,我們需要JUnit

如何將 JUnit 連接到項目

問題是如何將其連接到項目。對於那些了解情況的人來說,我不會選擇Maven,因為這是一個完全不同的故事。;) 開啟專案結構 Ctrl + Alt + Shift + S -> Libraries -> 點擊 + (New Project Library) -> select from Maven, JUnit 第 I 部分 - 2然後我們看到這樣一個窗口,在搜尋欄中輸入“junit:junit:4.12” ,等到找到->確定!-> 好的! JUnit 第 I 部分 - 3您應該得到這個結果 JUnit 第 I 部分 - 4點擊 OK,恭喜 JUnit 已加入專案。讓我們繼續。現在我們需要為 Java 類別建立測試,將遊標放在類別的名稱上User -> 按 Alt + Enter -> 選擇建立測試。我們應該看到一個窗口,在其中我們需要選擇 JUnit4 庫 -> 選擇我們要測試的方法 -> OK JUnit 第 I 部分 - 5這個想法本身將創建一個類UserTest,在這個類中我們將用測試覆蓋我們的程式碼。讓我們開始吧:

我們的第一個@Test

讓我們創建第一個@Test方法getAllUsers()- 這是一個應該返回所有用戶的方法。測試將如下所示:
@Test
public void getAllUsers() {
    // create test data
    User user = new User("Eugene", 35, Sex.MALE);
    User user1 = new User("Marina", 34, Sex.FEMALE);
    User user2 = new User("Alina", 7, Sex.FEMALE);

    //create an expected list and fill it with the data of our method
    List<User> expected = User.getAllUsers();

    //create actual list put data in it for comparison
    //what we expect the method to return
    List<User> actual = new ArrayList<>();
    actual.add(user);
    actual.add(user1);
    actual.add(user2);

    //run the test if the list expected and actual are not equal
    //the test will fail, read the test results in the console
    Assert.assertEquals(expected, actual);
}
這裡我們創建幾個測試用戶 -> 創建一個列表expected ,我們將在其中放置其方法將返回給我們的用戶getAllUsers()-> 創建一個列表actual ,在其中我們將放置我們假設 Assert.assertEquals getAllUsers()(actual, Expected) 方法的用戶將被使用,我們將把檢查過的和當前的列表傳遞給它。此方法將測試提供的清單中的物件並傳回測試結果。該方法將比較物件的所有字段,如果存在繼承,甚至會遍歷父物件的字段。讓我們執行第一個測試... JUnit 第一部分 - 6測試成功完成。現在讓我們嘗試讓測試失敗,為此我們需要更改其中一個測試列表,我們將透過註解掉向列表新增一個使用者來實現此目的actual
@Test
public void getAllUsers() {
    // create test data
    User user = new User("Eugene", 35, Sex.MALE);
    User user1 = new User("Marina", 34, Sex.FEMALE);
    User user2 = new User("Alina", 7, Sex.FEMALE);

    //create an expected list and fill it with the data of our method
    List<User> expected = User.getAllUsers();

    //create actual list put data in it for comparison
    //what we expect the method to return
    List<User> actual = new ArrayList<>();
    actual.add(user);
    actual.add(user1);
    //actual.add(user2);

    //run the test if the list expected and actual are not equal
    //the test will fail, read the test results in the console
    Assert.assertEquals(expected, actual);
}
我們執行測試並看到以下內容: JUnit 第 I 部分 - 7現在我們可以看一下測試失敗的原因。在這裡我們看到檢查清單中的使用者比目前清單中的使用者多。這就是失敗的原因。我們可以在 main 中檢查一下嗎?JUnit : main = 1 : 0。讓我們看看如果測試包含完全不同的對象,測試會是什麼樣子,讓我們這樣做:
@Test
public void getAllUsers() {
    // create test data
    User user = new User("Eugene", 35, Sex.MALE);
    User user1 = new User("Marina", 34, Sex.FEMALE);
    User user2 = new User("Alina", 7, Sex.FEMALE);

    //create an expected list and fill it with the data of our method
    List<User> expected = User.getAllUsers();

    //create actual list put data in it for comparison
    //what we expect the method to return
    List<User> actual = new ArrayList<>();
    actual.add(new User("User1", 1, Sex.MALE));
    actual.add(new User("User2", 2, Sex.FEMALE));
    actual.add(new User("User3", 3, Sex.MALE));

    //run the test if the list expected and actual are not equal
    //the test will fail, read the test results in the console
    Assert.assertEquals(expected, actual);
}
這就是控制台中將出現的內容: JUnit 第 I 部分 - 8在這裡您可以立即看到比較列表中有不同的用戶,我們也可以單擊&ltClick to see Difference>我們將獲得一個窗口,在其中我們可以詳細查看我們有哪些數據問題與. IDEA將突出顯示所有存在差異的領域。 JUnit 第 I 部分 - 9main這會發生嗎?- 不。getAllUsers()JUnit : main = 2 : 0 好吧,讓我們繼續,我們還有一堆方法需要測試),但是等等,檢查方法是否會返回給我們也不錯,因為那是我們如何處理驗證器捕獲的JavaRushnull任務) 。就這樣吧,三戈比的事…
@Test
public void getAllUsers_NO_NULL() {
    //add check for null
    List<User> expected = User.getAllUsers();
    Assert.assertNotNull(expected);
}
是的,是的,驗證器大致就是這樣捕獲我們的糟糕程式碼的null;)現在讓我們執行這個測試,看看它向我們展示了什麼。而且會顯示錯誤,怎麼辦???這裡怎麼會出現測試錯誤))) JUnit 第 I 部分 - 10在這裡我們可以收穫用測試覆蓋我們的程式碼的第一個成果。你還記得,allUsers 我們​​在建構函式中初始化了該字段,這意味著在呼叫該方法時getAllUsers(),我們將引用一個尚未初始化的物件。讓我們編輯它,從建構函數中刪除初始化,並在聲明欄位時執行此操作。
private static Map<Integer, User> allUsers = new HashMap<>();

    public User(String name, int age, Sex sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;

        if (!hasUser()) {
            countId++;
            this.id = countId;
            allUsers.put(id, this);
        }
    }
讓我們運行測試,現在一切都很好。 JUnit 第 I 部分 - 11我認為在 main 中捕獲 NPE 並不容易,我想你會同意計數是 JUnit: main = 3: 0 然後我將用測試覆蓋所有方法,讓你看看它會是什麼樣子...現在我們的測試類別如下圖所示:
package user;

import org.junit.Assert;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

import static org.junit.Assert.*;

public class UserTest {

    @Test
    public void getAllUsers() {
        // create test data
        User user = new User("Eugene", 35, Sex.MALE);
        User user1 = new User("Marina", 34, Sex.FEMALE);
        User user2 = new User("Alina", 7, Sex.FEMALE);

        //create an expected list and fill it with the data of our method
        List<User> expected = User.getAllUsers();

        //create actual list put data in it for comparison
        //what we expect the method to return
        List<User> actual = new ArrayList<>();
        actual.add(user);
        actual.add(user1);
        actual.add(user2);

        //run the test if the list expected and actual are not equal
        //the test will fail, read the test results in the console
        Assert.assertEquals(expected, actual);
    }

    @Test
    public void getAllUsers_NO_NULL() {
        //add check for null
        List<User> expected = User.getAllUsers();
        Assert.assertNotNull(expected);
    }

    @Test
    public void getAllUsers_MALE() {
        User user = new User("Eugene", 35, Sex.MALE);
        User user1 = new User("Marina", 34, Sex.FEMALE);
        User user2 = new User("Alina", 7, Sex.FEMALE);

        List<User> expected = User.getAllUsers(Sex.MALE);

        List<User> actual = new ArrayList<>();
        actual.add(user);

        Assert.assertEquals(expected, actual);
    }

    @Test
    public void getAllUsers_MALE_NO_NULL() {
        //add check for null
        List<User> expected = User.getAllUsers(Sex.MALE);
        Assert.assertNotNull(expected);
    }

    @Test
    public void getAllUsers_FEMALE() {
        User user = new User("Eugene", 35, Sex.MALE);
        User user1 = new User("Marina", 34, Sex.FEMALE);
        User user2 = new User("Alina", 7, Sex.FEMALE);

        List<User> expected = User.getAllUsers(Sex.FEMALE);

        List<User> actual = new ArrayList<>();
        actual.add(user1);
        actual.add(user2);

        Assert.assertEquals(expected, actual);
    }

    @Test
    public void getAllUsers_FEMALE_NO_NULL() {
        //add check for null
        List<User> expected = User.getAllUsers(Sex.FEMALE);
        Assert.assertNotNull(expected);
    }

    @Test
    public void getHowManyUsers() {
        User user = new User("Eugene", 35, Sex.MALE);
        User user1 = new User("Marina", 34, Sex.FEMALE);
        User user2 = new User("Alina", 7, Sex.FEMALE);

        int expected = User.getHowManyUsers();

        int actual = 3;

        Assert.assertEquals(expected, actual);
    }

    @Test
    public void getHowManyUsers_MALE() {
        User user = new User("Eugene", 35, Sex.MALE);
        User user1 = new User("Marina", 34, Sex.FEMALE);
        User user2 = new User("Alina", 7, Sex.FEMALE);

        int expected = User.getHowManyUsers(Sex.MALE);

        int actual = 1;

        Assert.assertEquals(expected, actual);
    }

    @Test
    public void getHowManyUsers_FEMALE() {
        User user = new User("Eugene", 35, Sex.MALE);
        User user1 = new User("Marina", 34, Sex.FEMALE);
        User user2 = new User("Alina", 7, Sex.FEMALE);

        int expected = User.getHowManyUsers(Sex.FEMALE);

        int actual = 2;

        Assert.assertEquals(expected, actual);
    }

    @Test
    public void getAllAgeUsers() {
        User user = new User("Eugene", 35, Sex.MALE);
        User user1 = new User("Marina", 34, Sex.FEMALE);
        User user2 = new User("Alina", 7, Sex.FEMALE);

        int expected = User.getAllAgeUsers();

        int actual = 35 + 34 + 7;

        Assert.assertEquals(expected, actual);
    }

    @Test
    public void getAllAgeUsers_MALE() {
        User user = new User("Eugene", 35, Sex.MALE);
        User user1 = new User("Marina", 34, Sex.FEMALE);
        User user2 = new User("Alina", 7, Sex.FEMALE);

        int expected = User.getAllAgeUsers(Sex.MALE);

        int actual = 35;

        Assert.assertEquals(expected, actual);
    }

    @Test
    public void getAllAgeUsers_FEMALE() {
        User user = new User("Eugene", 35, Sex.MALE);
        User user1 = new User("Marina", 34, Sex.FEMALE);
        User user2 = new User("Alina", 7, Sex.FEMALE);

        int expected = User.getAllAgeUsers(Sex.FEMALE);

        int actual = 34 + 7;

        Assert.assertEquals(expected, actual);
    }
}
是的,事實證明它並不小,但是在處理大型專案時會發生什麼。這裡可以減少什麼?在評估完所有內容之後,您可以看到我們在每個測試中創建了測試數據,並且這裡註釋可以幫助我們。我們假設 @Before- 該註釋@Before表明該方法將在每個被測試的方法之前執行@Test。這就是我們現在有註解的測試類別的樣子@Before
package user;

import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

import static org.junit.Assert.*;

public class UserTest {
    private User user;
    private User user1;
    private User user2;

    @Before
    public void setUp() throws Exception {
        user = new User("Eugene", 35, Sex.MALE);
        user1 = new User("Marina", 34, Sex.FEMALE);
        user2 = new User("Alina", 7, Sex.FEMALE);
    }

    @Test
    public void getAllUsers() {
        List<User> expected = User.getAllUsers();

        List<User> actual = new ArrayList<>();
        actual.add(user);
        actual.add(user1);
        actual.add(user2);

        Assert.assertEquals(expected, actual);
    }

    @Test
    public void getAllUsers_NO_NULL() {
        List<User> expected = User.getAllUsers();
        Assert.assertNotNull(expected);
    }

    @Test
    public void getAllUsers_MALE() {
        List<User> expected = User.getAllUsers(Sex.MALE);

        List<User> actual = new ArrayList<>();
        actual.add(user);

        Assert.assertEquals(expected, actual);
    }

    @Test
    public void getAllUsers_MALE_NO_NULL() {
        //add check for null
        List<User> expected = User.getAllUsers(Sex.MALE);
        Assert.assertNotNull(expected);
    }

    @Test
    public void getAllUsers_FEMALE() {
        List<User> expected = User.getAllUsers(Sex.FEMALE);

        List<User> actual = new ArrayList<>();
        actual.add(user1);
        actual.add(user2);

        Assert.assertEquals(expected, actual);
    }

    @Test
    public void getAllUsers_FEMALE_NO_NULL() {
        //add check for null
        List<User> expected = User.getAllUsers(Sex.FEMALE);
        Assert.assertNotNull(expected);
    }

    @Test
    public void getHowManyUsers() {
        int expected = User.getHowManyUsers();

        int actual = 3;

        Assert.assertEquals(expected, actual);
    }

    @Test
    public void getHowManyUsers_MALE() {
        int expected = User.getHowManyUsers(Sex.MALE);

        int actual = 1;

        Assert.assertEquals(expected, actual);
    }

    @Test
    public void getHowManyUsers_FEMALE() {
        int expected = User.getHowManyUsers(Sex.FEMALE);

        int actual = 2;

        Assert.assertEquals(expected, actual);
    }

    @Test
    public void getAllAgeUsers() {
        int expected = User.getAllAgeUsers();

        int actual = 35 + 34 + 7;

        Assert.assertEquals(expected, actual);
    }

    @Test
    public void getAllAgeUsers_MALE() {
        int expected = User.getAllAgeUsers(Sex.MALE);

        int actual = 35;

        Assert.assertEquals(expected, actual);
    }

    @Test
    public void getAllAgeUsers_FEMALE() {
        int expected = User.getAllAgeUsers(Sex.FEMALE);

        int actual = 34 + 7;

        Assert.assertEquals(expected, actual);
    }
}
好吧,你呢,它已經更有趣、更容易閱讀了;)這是 JUnit 註釋的清單;使用它們肯定更容易。
@Test – определяет что метод method() является тестовым.
@Before – указывает на то, что метод будет выполнятся перед каждым тестируемым методом @Test.
@After – указывает на то что метод будет выполнятся после каждого тестируемого метода @Test
@BeforeClass – указывает на то, что метод будет выполнятся в начале всех тестов,
а точней в момент запуска тестов(перед всеми тестами @Test).
@AfterClass – указывает на то, что метод будет выполнятся после всех тестов.
@Ignore – говорит, что метод будет проигнорирован в момент проведения тестирования.
(expected = Exception.class) – указывает на то, что в данном тестовом методе
вы преднамеренно ожидаете Exception.
(timeout = 100) – указывает, что тестируемый метод не должен занимать больше чем 100 миллисекунд.
用於檢查的主要類別方法Assert
fail(String) – указывает на то что бы тестовый метод завалился при этом выводя текстовое сообщение.
assertTrue([message], boolean condition) – проверяет, что логическое condition истинно.
assertsEquals([String message], expected, actual) – проверяет, что два значения совпадают.
Примечание: для массивов проверяются ссылки, а не содержание массивов.
assertNull([message], object) – проверяет, что an object является пустым null.
assertNotNull([message], object) – проверяет, что an object не является пустым null.
assertSame([String], expected, actual) – проверяет, что обе переменные относятся к одному an objectу.
assertNotSame([String], expected, actual) – проверяет, что обе переменные относятся к разным an objectм.
這就是我們如何在 Maven 中新增 JUnit 4.12 依賴項
<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.12</version>
  <scope>test</scope>
</dependency>
此處繼續 -> JUnit 第二部分
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION