@daniil14056

Как выглядит реальный пример теста JUNIT?

Уже в который раз хочу разобраться с тестами, и хоть убейте, не могу понять, чем они лучше простого system.out.print(). Сколько не писал тесты, во первых тратил больше времени, во вторых ВСЕГДА получал true результат. При том всегда заранее знал уже известный результат, я всегда знал что 2+2==4. Или вообще использую копию файла в тест файлах, там определяю класс mainTest c main и в нем делаю пример функционирования класса, но это демонстрация возможностей какая-то, а не тестирование. Вроде не чего сложного, но не пойму как их составлять
  • Вопрос задан
  • 478 просмотров
Решения вопроса 1
  • TheDeadOne
    @TheDeadOne
    Седой и строгий
    Пользу от тестов замечаешь только тогда, когда начинаешь писать что-то сложнее hello world'ов. Особенно хорошо их видно, когда приложение разрабатывается уже несколько лет и более, чем десятком разработчиков. Изменяешь какую-то часть кода, запускаешь тестирование и видишь, что теперь другой участок кода тестирование не проходит, так как в прошлом году у разработчика, которого ты даже не встречал, протекла абстракция.
    Ответ написан
Пригласить эксперта
Ответы на вопрос 3
  • @Symbol7
    Как и сказал Сергей Горностаев , пользу от Unit-тестов можно увидеть только в серьёзном и большом проекте, а так же при автоматических сборках проекта. Задача Unit-тестов проверить, правильно ли выполняется логика тестируемого метода и возвращает ли он ожидаемый результат. Желательно, не выходить за пределы тестируемого класса, то есть, если класс использует какие-то внешние ресурсы или другие классы, то стоит съэмулировать (замокать) эти ресурсы и классы, так как они должны быть протестированы отдельными тестами. Таким образом мы тестируем только код конкретного класса, предварительно зная, что будут возвращать нам другие классы.

    Допустим, у нас есть какой-то маппер книги из сущности БД в объект DTO. В этот маппер инжектится репозиторий книг, из которого по id можно получить книгу.
    public class BookMapper {
        @Inject
        private BookRepository bookRepository;
    
        public BookDTO mapToDTO(Integer id){
            Book book = bookRepository.findOne(id);
            return new BookDTO(book.getId(), book.getName());
        }
    }


    Наша задача протестировать логику этого маппера. Мы можем замокать репозиторий, так как сейчас тестируем не его (на него должны быть отдельные тесты), и проверить, вернёт ли нам маппер нужное DTO, если ему передать какой-то id. Настраиваем мок репозитория и вызываем нужный метод. После чего сравниваем ожидаемый результат, с полученным результатом:

    @RunWith(MockitoJUnitRunner.class)
    public class BookMapperTest {
        @Mock
        private BookRepository bookRepository;
    
        @InjectMocks
        private BookMapper bookMapper;
    
        @Test
        public void testMapToDTO() {
            // Мокаем репозиторий. Он возвращает конкретную книгу при передаче ему
            // конкретный id
            Book book = new Book(20, "Конституция");
            Mockito.when(bookRepository.findOne(20)).thenReturn(book);
    
            // Ожидаемая книга
            BookDTO expectedBook = new BookDTO(20, "Конституция");
    
            // Полученная из маппера книга
            BookDTO actualBook = bookMapper.mapToDTO(20);
    
            // Сравниваем ожидаемую книгу и полученную книгу
            Assert.assertEquals(expectedBook, actualBook);
        }
    }


    Это очень утрированный пример. Зато мы теперь можем быть уверены, что если кто-то когда-то поменяет класс маппера так, что он начнёт возвращать другой результат, то тест упадёт, что будет указывать на то, что в других классах, использующих этот маппер так же потенциально может быть ошибка.

    В данном случае пример совсем простой. На реальном коде нужно тестировать все уникальные сценарии работы метода. Например, если в методе есть ветвление if, перебор switch, бросание исключения и т.д., то необходимо протестировать каждый вариант.
    Ответ написан
  • Вы немного путаете TDD и unit-тестирование.
    Эти вещи перпендикулярные.
    TDD - это способ (методология) разработки программ.
    И там да, в начале тест (unit-test) должен быть красным.
    Unit-test это всего лишь инструмент, как например отладчик.
    Отладчик ведь тоже легко заменяется system.out.print()
    :-)
    Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через TM ID
Похожие вопросы