User Евгений Гродно
Евгений Гродно
36 уровень

JUnit part II

Статья из группы Random
продолжение начало тут -> JUnit part I
JUnit part II - 1
Еще хочу вам показать, как работает метод Assert.fail(String) – если будет вызван этот метод, тест будет провален. Удобно в случае если другие методы класса Assert не могут сделать нам проверку. Допустим нам нужно запретить принимать new String(“”). Попробуем это сделать на конструкторе запретим передавать name = “” || null, age = 0; Sex = null. Поехали … Я добавил дополнительные поля для тестирования

private User user;
private User user1;
private User user2;

private User userNotAdd;
private User userNotAdd1;
и изменил метод setUp()

@Before
public void setUp() throws Exception {
    user = new User("Евгений", 35, Sex.MALE);
    user1 = new User("Марина", 34, Sex.FEMALE);
    user2 = new User("Алина", 7, Sex.FEMALE);
    
    userNotAdd = new User("", 0, null);
    userNotAdd1 = new User(null, 0, null);
}
и добавил три метода теста

@Test
public void newUser_EMPTY_NAME() {
    for (User user : User.getAllUsers()){
        if (user.getName() != null && user.getName().isEmpty()) {
            Assert.fail("Попытка создания пользователя с пустым именем");
        }
    }
}

@Test
public void newUser_AGE_ZERO() {
    for (User user : User.getAllUsers()) {
        if (user.getAge() <= 0) {
            Assert.fail("Попытка создания пользователя c не допустимым возрастом");
        }
    }
}

@Test
public void newUser_SEX_NO_NULL() {
    for (User user : User.getAllUsers()) {
        if (user.getSex() == null) {
            Assert.fail("Попытка создания пользователя с указанием пола = null");
        }
    }
}
В тестах мы проходим по списку добавленных пользователей, и смотрим есть ли не допустимые данные. Запускаем тесты оптом, и видим такую картину... JUnit part II - 2 Тут видно, наши тесты для конструктора поломались, а так же зацепило еще пару тестов Теперь нам нужно изменить конструктор, чтобы он не добавлял в список пользователей, пользователя с недопустимыми параметрами, сделаем это так:

public User(String name, int age, Sex sex) {
    if (name != null && !name.isEmpty() && age > 0 && sex != null){
        this.name = name;
        this.age = age;
        this.sex = sex;

        if (!hasUser()) {
            countId++;
            this.id = countId;
            allUsers.put(id, this);
        }
    }
}
Запускаем наши тесты и видим, что у нас все по красоте JUnit part II - 3 Подведем итог, JUnit отличный инструмент для покрытия своего кода тестами. JUnit сработает еще лучше, в связке с Maven, при сборке проекта, Maven обязательно проведет все тесты, и потом соберет наш готовый проект, но если тесты будут провалены, проект не будет собран, и мы будем знать причины, и так будет легче разобраться где именно поломка. Второй плюс JUnit это случай Рефакторинга, тесты JUnit помогут нам проследить чтобы логика нашей программы не поломалась. А в больших проектах без системы автоматического тестирования жизнь не возможна, хотя может и возможна, но двигаться ваш проект будет со скоростью черепахи … или как то так … JUnit part II - 4 Если мы хорошо покроем тестами наш код, то можем быть уверены, что у нашего клиента, наш продукт будет отлично работать. P/S Выражаю огромную благодарность Сергееву Виктору!!! Вот ссылки на видео урок, в котором он нас обучал: Спасибо за внимание!!! Хорошего вам настроения!!! И да спаси вас Бог от индускода!!! ...еще если у кого будет интерес покапаться в исходном коде для статьи... стучитесь... с поделюсь тут начало — JUnit part I
Комментарии (18)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
LuneFox Уровень 34, Москва, Россия Expert
15 января 2022
Большое спасибо за статью, теперь я хотя бы знаю, как выглядят эти тесты, о которых все говорят, и что знает "покрывать код тестами". Раньше я себе это как-то абстрактно представлял, как покрытие деревяшки лаком. Думал: "Что за сленг такой?". А теперь сам попробовал и понял, что это очень вкусно (хотя, наверное, рутинно покрывать огромный код всяческими тестами это та ещё скукотища, да?). Но в любом случае это круче, чем постоянно копаться в main и городить огород из sout-ов. Сравнимо с использованием дебаггера, наверное.
Санек Уровень 35, Одесса, Украина Expert
20 мая 2021

public User(String name, int age, Sex sex) {
    if (name != null && !name.isEmpty() && age > 0 && sex != null){
        this.name = name;
        this.age = age;
        this.sex = sex;

        if (!hasUser()) {
            countId++;
            this.id = countId;
            allUsers.put(id, this);
        }
    }
}
Лично я бросал бы IlligalArgumentException и ожидал его в тестах. Но спасибо за пояснения метода fail().
Дмитрий Ващенко Уровень 27, Vsevolozhsk
19 мая 2021
Привет всем, автору спасибо за статью. Очень полезно и познавательно. Хотел бы только отметить, что возраст может быть равен 0, так что проверки что он больше нуля могут вызвать интересные последствия при реальной работе подобного приложения, а тесты будут проходить. ИМХО
Егор BLR Уровень 12, Минск, Беларусь
22 февраля 2021
откуда getName()?
Александр Колосов Уровень 36, Санкт-Петербург, Россия
22 апреля 2019
Благодарю. Очень в тему пришлось.
Марина Уровень 28, Белгород, Россия
14 марта 2019
Спасибо большое за статью! Но когда я делала первые свои тесты, они не проходили и пришлось поправить конструктор своих объектов. Возможно, я что-то не так поняла и стала вносить логику в конструктор (а именно проверка параметров входящих), но что мне сказали, что логику в конструктор лучше не вносить и воспользоваться, например паттерном фабрика (то есть вовсе не создавать объект и не вызывать его конструктор, если параметры не соответствуют).
Denis Shadrin Уровень 31, Новосибирск, Россия
1 марта 2019
Очень крутая статья, все понятно и доступно описано, спасибо большое Евгению
Андрей Уровень 29, Самара
7 февраля 2019
Поправьте если не прав, но мне кажется у вас нет проверки на null @Test public void newUser_EMPTY_NAME() { for (User user : User.getAllUsers()){ if (user.getName() != null && user.getName().isEmpty()) { Assert.fail("Попытка создания пользователя с пустым именем"); } } } Может так ? if (user.getName() == null || user.getName().isEmpty()) {
Ваня Жуков Уровень 40, Санкт-Петербург, Россия
4 мая 2018

@Test
public void newUser_EMPTY_NAME() {
    for (User user : User.getAllUsers()){
        if (user.getName().isEmpty() && user.getName() != null) {  // По идее тут NPE
            Assert.fail("Попытка создания пользователя с пустым именем");
        }
    }
}
Pavlo Plynko Уровень 40, Киев, Украина Expert
1 мая 2018
Суперская книга: Practical Unit Testing with JUnit and Mockito Подоедет даже людям со слабым английским, заодно практика чтения будет. Автор пишет простым, не академическим языком, вставляет шутки и т.д. Рекомендую всем кому интересно покопаться и досконально разобраться с юнит тестированием.