Написание модульных тестов на Java с использованием JUnit и Mockito
Despite several efforts to promote unit testing by the programming community and emphasize unit testing by many notable programmers, it’s still one of the lacking practices.
5 Best JUnit and Test Driven Development Books for Java Developers
My favorite books to learn are Test-Driven Development (TDD), JUnit, Mockito, and Unit testing in Java in depth.
Hello Java Programmers, If you want to learn JUnit and Test Driven Development in Java or want to improve your TDD skills and looking for the best resources like books and online courses then you have come to the right place.
Earlier, I have shared the best JUnit courses for Java developers, and in this article, I am going to share the best books you can read to learn Test Driven Development in Java and essential testing tools like JUnit and Mockito.
If you have done some professional Java development, you know that Unit testing is an essential thing to learn to adapt. This is the single most practice a professional developer should learn in my opinion. This is also one skill that differentiates an excellent programmer from a professional programmer.
It’s one way you can see how disciplined a programmer is?
It’s also the best way to write clean code; a code that can stand the test of time, a flexible code to accommodate future changes, and a code that you don’t afraid of while changing.
Despite several efforts to promote unit testing by the programming community and emphasize unit testing by many notable programmers, it’s still one of the lacking practices.
To encourage developers to do unit testing, I try to make it natural rather than a special thing. I have found that it’s not that programmer doesn’t want to test, or they don’t have time, it’s because they don’t really know how to unit test a non-trivial code.
It’s easy for someone to write a unit test for palindrome or prime factor program, but when it comes to writing unit test for a feature you are developing which involves database connection, threads, has a dependency on other module and don’t have a clear entry point, programmer’s lost their zeal and enthusiasm.
Since users or managers don’t care about unit tests, the programmer really doesn’t push themselves to the level they usually do to make a functional code working. How do we solve this problem? How do you develop that code sense to write a unit test? How do you decompose a big feature into small units which can be independently testable?
Does it sound like I am talking about Test-driven development (TDD)? Well, Yes. Even if you don’t follow TDD in its true sense, it will help you learn many tricks and techniques to unit test your code.
On the flip side, It’s one area where the senior developer must shine; it’s their job to promote best practices, code reviews, and unit testing among the next generation of Java developers.
This article will share the 5 Best books to learn unit testing, TDD, and JUnit, which you would love to read, which will help you learn unit testing and master the art of writing good tests. Unit testing and JUnit are synonymous in the Java world, so most of this book will teach you unit testing using JUnit.
This is good because a sound knowledge of how JUnit works and how you can use different JUnit annotations will encourage you to write more tests. If you also need online courses to go along with this book, I highly recommend you check JUnit and Mockito Crash Course on Udemy.
JUnit and Mockito Crash Course: Learn JUnit and Mockito Unit Tests
Bharath Thippireddy is an Entrepreneur, Software Architect, and Public Speaker who has trained 400000 + students across…
I found that we learn better when we combine an online course with a book. The course provides a quick start and helps in setup, while the book provides in-depth knowledge.
Top 5 JUnit and Test Driven Development Books for Beginner and Experienced Java Programmers
Here is my list of good books to master unit testing, JUnit, and Test Driven Development (TDD) for Java professionals. Though concept like unit testing is language agnostic, it makes sense to learn tricks in the language you best understand.
Since tools and techniques are different for each language, the core concept remains the same, and some techniques are general enough to be utilized in other object-oriented languages like C++ or C#.
1. Pragmatic Unit testing in Java with JUnit
This is the first book I read on unit testing and JUnit, and I still love to read it when I have some free time. It’s a short book, but whatever is written is absolute gold. All, Jeff Langr, Andy Hunt, and Dave Thomas have done brilliant work to first introduce the concept and process of unit testing before introducing JUnit.
The explanation flows through, and you feel you are learning something by following a small number of examples given in this book. Yes, the book is kind of light on examples, but the good thing is that every example was explained very well.
I still remember the CORRECT acronym I learned from this book, which helps you think about boundary conditions tests. CORRECT stands for
- Conformance — does the value conform to the expected format?
- Ordering — does value is in the expected order?
- Range — does value is in the expected range?
- Reference — does code reference anything external which is not in direct control of the code itself?
- Existence — does the value exists? (null, non-null, present or absent in Collection)
- Cardinality — Are there exactly enough values?
- Time (absolute and relative) — Is everything happening in order? At the right time? In time?
This acronym will help you to write a complete test for boundary conditions. Another acronym I like from this book is called A-TRIP, which demonstrates the properties of a good unit test. A-TRIP stands for:
By reading this book, you will learn how to unit test your Java application, how to write a good test, what to test, boundary conditions, dealing with design issues to make your code more testable, and testing Gotchas like randomly failing/passing tests, test working on one machine but not on others, tests taking too long to run, etc.
Here is the link to get this book — Pragmatic Unit testing in Java with JUnit
In short, a must-read unit testing book for Java developers who like to unit tests their programs. If you like online courses, you can also combine this with the Java Unit Tests for Beginners course from Udemy to get the best of both worlds.
Написание модульных тестов на Java с использованием JUnit и Mockito
Статья, первоначально опубликованная на моем личном веб-сайте в разделе Использование JUnit и Mockito для модульного тестирования… С тегами java, junit, mockito, unittest.
- Автор записи Автор: pazvanti
- Дата записи 18.11.2021
Статья, первоначально опубликованная на моем личном веб-сайте в разделе Использование JUnit и Mockito для модульного тестирования на Java
Тестирование важно для всех программных систем и приложений. Это поможет вам легко находить ошибки и предотвратит сбои и простои вашего приложения, особенно если система развивается с течением времени. Поначалу это может показаться не критичным, но по мере роста и усложнения системы вероятность появления незамеченной ошибки возрастает.
Для Java доступно множество платформ тестирования, причем JUnit является одной из наиболее широко используемых. В этой статье мы рассмотрим несколько простых API, предлагаемых JUnit, и то, как их использовать для модульного тестирования. В большинстве случаев JUnit будет недостаточно, и часто встречается комбинация JUnit + Mockito.
Для тех, кто не знает, Mockito – это еще одна платформа, используемая для тестирования, в которой вы имитируете определенные классы, чтобы вы могли легко изолировать класс, который хотите протестировать, и контролировать вывод других классов или компонентов, которые используются классом. Он также предлагает возможность проверить, был ли вызван макет, сколько раз и другие полезные функции.
Проверка результата в JUnit
Простой и наиболее широко используемой функцией модульного тестирования является проверка того, что полученный результат соответствует ожидаемому. Это базовая функция, которую вы будете часто использовать при написании тестов, потому что необходимо проверить, действительно ли ваш метод возвращает правильный ответ. Это достигается с помощью
methods. “`java @Test public void aSimpleTest()
Примечание для утверждения двойной переменной. Даже если числа на самом деле не равны, тест все равно проходит. Это связано с тем, что последний параметр в методе представляет точность. Это отклонение, которое мы допускаем в результате и все еще считаем его допустимым. Если вы хотите повысить точность, просто уменьшите дельту.
Пользовательское сообщение об ошибке для теста
Иногда важно показать пользовательское сообщение на случай сбоя теста. Эта функция экономит много времени при автоматической сборке, когда трудно получить доступ к полной трассировке стека. Используя пользовательское сообщение, вы можете легко распечатать, что было неправильно, какая переменная была неправильной, или любую информацию, которая поможет вам (или другому инженеру) понять, что произошло. Это делается с помощью перегруженных методов из Assert, которые сначала имеют параметр message, как показано ниже.
@Test public void aSimpleTestWithMessage()
Проверка результатов со сложными объектами в JUnit
В большинстве случаев у вас будут сложные объекты с несколькими полями. Проверить их так же легко, как и простые. JUnit использует метод equals(), чтобы проверить, что полученный вами результат идентичен ожидаемому. Вот почему в этом случае важно иметь правильно написанный метод equals() для вашего объекта. Давайте посмотрим на этот класс данных:
public class DataClass < private String field1; private String field2; private int field3; public DataClass(String field1, String field2, int field3) < this.field1 = field1; this.field2 = field2; this.field3 = field3; >@Override public boolean equals(Object o) < if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; DataClass dataClass = (DataClass) o; return Objects.equals(field1, dataClass.field1) && Objects.equals(field2, dataClass.field2) && Objects.equals(field3, dataClass.field3); >>
Теперь мы можем написать тест, и поскольку метод equals() написан правильно, тест пройдет, даже если есть два разных объекта:
@Test public void testComplexObject()
Все это весело, однако в некоторых сценариях вы хотите убедиться, что возвращается ТОЧНО такой же объект. Это достигается с помощью метода Assert.same(). Он работает точно так же, как Assert.assertEquals(), однако проверяет не содержимое, а фактическую ссылку на объект. Используя его, тест пройдет тогда и только тогда, когда ожидаемое и результат совпадут.
Проверка исключения создается в JUnit
Еще одной полезной функцией является проверка того, что метод действительно создает правильное исключение при получении неверных входных данных. Существует несколько способов сделать это, но самый простой – указать ожидаемый параметр в аннотации @test. Это сообщит JUnit, что тест выдаст предоставленное исключение, если оно правильное.
@Test(expected = NumberFormatException.class) public void testNumberParse()
Как высмеять ваш ответ с помощью Mockito
Сложные системы имеют множество компонентов и классов, которые взаимодействуют друг с другом. Для таких систем сложно протестировать все сразу, либо потому, что вы не знаете, как работает каждый компонент, либо потому, что потребуется слишком много времени, чтобы правильно все настроить и выполнить тесты. Вот почему было введено понятие насмешек. Макет – это объект, который копирует API вашего класса, но не выполняет никакой обработки. Вместо этого он просто возвращает то, что вы ему говорите.
Это полезно для модульного тестирования, поскольку позволит вам сосредоточиться только на одном классе (том, который вы действительно хотите протестировать), игнорируя внутреннюю работу других объектов, используемых вашим классом. В качестве примера предположим, что вы хотите протестировать службу и проверить правильность агрегирования. Служба использует один или несколько DAO для извлечения необработанных данных из базы данных. Вы не хотите, чтобы данные записывались в БД, и вам не нужны более медленные тесты из-за необходимости каждый раз обращаться к БД.
Что вы делаете в этом случае, так это издеваетесь над DAO и говорите макету, что нужно возвращать для каждого теста. Это легко сделать с помощью Mockito.
private static MyDao mockDao; @BeforeClass public static void setup() < // Initialize the mock of the type MyDao mockDao = Mockito.mock(MyDao.class); >
Теперь вы можете написать свой тест, установив издевательский объект DAO в свою службу (с помощью установщика или с помощью механизма внедрения зависимостей) и указав, что DAO должен возвращать при вызове. Вот наши оригинальные объекты. Мы хотим проверить, работает ли сервис, даже если DAO еще не написан.
public class MyService < private MyDao dao; public void setDao(MyDao dao) < this.dao = dao; >public boolean process(String id) < if (id == null) return false; Listall = dao.getAll(); if (all == null || all.isEmpty()) return false; DataClass ofInterest = dao.get(id); if (ofInterest == null) return false; // do some processing return true; > >
public class MyDao < public ListgetAll() < return Collections.emptyList(); >public DataClass get(String id) < return null; >public void save() < // do nothing >>
Мы установим макет DAO в качестве объекта для нашей службы и попросим его возвращать правильные данные при вызове. Таким образом, мы ускоряем разработку, а также выполнение тестов.
@Test public void testService()
Метод Mockito.when() сообщает макету, что возвращать, когда он вызывается. Кроме того, вы можете указать параметр, который следует ожидать для методов, имеющих параметры, используя предоставленные вспомогательные методы: Mockito.eq, Mockito.any, Mockito.matches, Mockito.same и т. Д.
Подготовка и очистка тестовых данных
В сложных системах некоторые тесты становятся более сложными и требуют взаимодействия с другими системами или частями кода, чтобы заставить их работать должным образом. Необходимо либо записать некоторые тестовые данные, либо включить некоторые функции или функциональные возможности, либо просто установить некоторые переменные среды. Вы можете сделать это для каждого теста в наборе или использовать функции “До” и “После” JUnit, чтобы убедиться, что все правильно инициализировано и очищено.
В JUnit есть 4 важных аннотации, которые помогают в этом: @Before и @BeforeClass наряду с @After и @AfterClass.
Методы, помеченные символом @Before, выполняются перед каждым тестом в классе. Если в тестовом классе у вас есть несколько методов, помеченных @test, @Before будет выполняться непосредственно перед запуском каждого метода тестирования. Аналогично, @After выполняется после каждого теста в костюме.
Две другие аннотации, @BeforeClass и @AfterClass, будут выполнены только один раз, ровно перед запуском любого теста и сразу после завершения всех тестов, независимо от результатов теста. Эти методы очень полезны для подготовки вашей среды и записи любых тестовых данных, а также для выполнения необходимой очистки, чтобы убедиться, что среда находится в чистом состоянии без зависших данных.
Выводы
Как видно, Java с помощью JUnit и Mockito предоставляет все необходимые функции и функциональные возможности, необходимые для написания модульных тестов для вашего кода. Даже если это может показаться неудобством, наличие хорошо написанных тестов поможет вам быстрее выявлять ошибки, а также поддерживать надежную и стабильную программную систему.
Как всегда, вы можете скачать полные образцы кодов на моем личном веб-сайте.
Статья, первоначально опубликованная на моем личном веб-сайте в разделе Использование JUnit и Mockito для модульного тестирования на Java
Читайте ещё по теме:
- Написание эффективных модульных тестов на Java с помощью Mockito
- Инъекция Мокито Издевается над весенними бобами
- Вложенные тесты JUnit 5
- Примеры тайм-аутов JUnit 5
- Примеры предположений JUnit 5
- Примеры условных тестов JUnit 5
- Как запустить модульный тест с помощью Maven