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

    @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, бросание исключения и т.д., то необходимо протестировать каждый вариант.
    Ответ написан
    Комментировать