JavaRush /Java 博客 /Random-ZH /JUnit 第一部分

JUnit 第一部分

已在 Random-ZH 群组中发布

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