How to start with unit testing in Java: A complete introduction to JUnit 5

Originally published by YURI MEDNIKOV at mednikov.net 

In this post, I would like to focus on unit testing in Java with JUnit5 library. It introduced new features and approaches to testing, compare to older JUnit 4 version, that are worth to check. We would overview what is unit test and why to test; how to install JUnit 5 in your project; what is a basic test structure; how to use Asseritions API and how to combine multiple tests in a test suite.

What is unit testing?

Unit testing is a level of software testing, when we test individual software's components in isolation. For example, we have UserService. It may have various connected dependencies, like UserDAO to connect to a datasource, or EmailProvider to send confirmation emails. But for unit testing, we isolate UserService and may mock connected dependencies (how to do mocking, we would see in the next chapter).

The unit testing offers us a number of benefits, to name few:

  • It increases our confidence, when we change code. If unit tests are good written and if they are run every time any code is changed, we can notice any failures, when we introduce new features
  • It serves as documentation. Certanly, documenting your code includes several instruments, and unit testing is one of them - it describes an expected behaviour of your code to other developers.
  • It makes your code more reusable, as for good unit tests, code components should be modular.

These advantages are just few of numerous, that are provided us by unit testing. Now, when we defined what is unit testing and why do we use it, we are ready to move to JUnit5.

Install JUnit5

Build tools support

For a native support of JUnit5 you should have a version of Gradle 4.6+ or Maven 2.22.0+.

For Maven you need to add to your Pom.xml:

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>{$version}</version>
    <scope>test</scope>
</dependency>

For Gradle add to build.gradle:

testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '$version'

You could find the latest version of JUnit5 in the official repository. By the way, if you would use JUnit 5 with Vert.x framework, there is Vert.x JUnit5 extension.

IDE support

Intelij IDEA supports JUnit5 natively since 2016.2, and Eclipse since 4.7.1a.

An anatomy of unit test

Basic structure

Consider this example: we have a program, that performs a linear search of a number in an array of integers. Here is a main class, that we place in the src/main/java/ folder:

class LinearSearcher(){
private int[] data;

LinearSearcher(int[] arr){
this.data = arr;
}

int getPositionOfNumber(int value){
int n = data.length;
for(int p = 0; i < n; i++)
{
if(data[p] == value)
return p;
}
return -1;
}
}

And then add this second code to the src/test/java folder:

class LinearSearcherTest{

private static LinearSearcher searcher;

//before
@BeforeAll
static void setup(){
   int[] array = {2, 3, 4, 10, 40};
   searcher = new LinearSearcher(array);
}

//Actual test methods
@Test
void getPosition(){
   int result = searcher.getPositionOfNumber(10);
   Assertions.assertEquals(3,result);
}

@Test
void noSuchNumber(){
   int result = searcher.getPositionOfNumber(55);
   Assertions.assertEquals(-1, result);
}

//after
@AfterAll
static void finish(){
   System.out.println("Tests are finished!");
}

}

Let check what we did in this code. We introduced a new class, LinearSearcher that has one method - getPostionOfNumber that returns the position of value in the array, or returns -1, if value is not presented in the array.

In second class, LinearSearcherTest we actually do unit testing. We expect two scenarios: when we have a number in the array (in our case 10), we expect to receive its position (3). If no such number is presented (for example 55), our searcher should return -1. Now, you can run this code and check results.

Before methods

You could note two methods annotated respectively with @BeforeAll and @AfterAll. What do they do? First method corresponds to Before methods. There are two of them:

  • @BeforeAll - the static method that will be executed once before all@Test method in the current class.
  • @BeforeEach - the method that will be executed before each @Test method in the current class.

These methods are handy to setup unit test environment (for example, to create instances).

After methods

As there are before methods, there are After methods. There is also a couple of them:

  • @AfterAll - the static method will be executed once after all @Test methods in the current class.
  • @AfterEach - the method that will be executed after each @Test method in the current class.

Using standard Assertions API

Assertions API is a collection of utility methods that support asserting conditions in tests. There are numerous available methods, however we would focus on most important of them.

Assert not null

When we need to assert, that actual object is not null, we can use this method:

assertNotNull(Object obj);

If object is not null, the method passes, if not - fails.

Assert Equals

This group includes many methods, so I would not provide your all overloaded versions, but would focus a general signature:

assertEquals(expected_value, actual_value, optional_message);

These methods have two required arguments and one optional argument:

  • expected_value = the result, we want to receive
  • actual_value = the tested value
  • optional_ message = String message, that would be displayed to STDOUT if method is failed.

Values can be of primitive types: int, double, float, long, short, boolean, char, byte, as well Strings and Objects. To this group, we can add these test methods:

  • assertArrayEquals - check that expected and actual arrays are equal. Arrays are of primitive types
  • AssertFalse and AssertTrue - check that supplied boolean condition is false or true respectively
  • assertIterableEquals - same as assertArrayEquals, but for Iterables(e.g. List, Set etc)

As I mentioned, there are many overloaded methods in this section, so it worth to explore official documentation for concrete signatures.

Assert throws

This is an innovation of JUnit5. Consider, that you have a method that throws an exception:

Car findCarById(String id) throws FailedProviderException;

This method retrieves an individual Car from an underlaying database by its ID, and throws FailedProviderException when there is a problem with database. In other words, we wrap in an interface possible data source exceptions (like SQLException or respected for NoSQL databases) and achieve its independence from the implementation.

How do we test that exception is thrown? Before, in JUnit4 we used annotations:

@Test(expected = FailedProviderException.class)
void exceptionThrownTest() throws Exception{
Car result = repository.findCarById(“non-existing-id”);
}

Btw, same idea is used in TestNG. In JUnit5 was introduced assertThrowsmethod. Take a look, how we would deal with same situation:

@Test
void exceptionThrownTest(){
Assertions.assertThrows(FailedProviderException.class, ()->{
Car result = repository.findCarById(“non-existing-id”);
});
}

This method signature has two components:

  1. Expected exception to be thrown
  2. Lambda expression of Executable, that contains a code snippet, that potentially throws the exception.

Again, as we aforesaid methods of assertEquals’s group, we can provide an optional message of String as third argument.

Assert timeout

When we need to assert, that test is finished in a defined timeout, we can use this method:

assertTimeout(Duration timeout, Executable executable)

The idea is same as with assertThrows method, but there we specify timeout. Second argument is a same Executable lambda expression. Third optional component is a String message. Let consider an example:

@Test
void in3secondsTest(){
Assertions.assertTimeout(Duration.ofSeconds(3), ()->{
//some code
});
}

Please note, that this method uses Duration API to specify timeframe. It has several handy methods, like ofSeconds(), ofMills() etc. If you are not familiar with it, don’t be shy to check this tutorial.

Fail

Finally, what if we need to fail test? Just use Assertions.fail() method. Again, there are several of them:

  • fail (String message) = Fails a test with the given failure message.
  • fail (String message, Throwable cause) = Fails a test with the given failure message as well as the underlying cause.
  • fail (Throwable cause) = Fails a test with the given underlying cause.

Creating test suites

If you have several unit tests and you want to execute them in one load, you can create a test suite.

This approach allows you to run tests spread into multiple test classes and different packages.

Suppose, that we have tests TestA, TestB, TestC, that divided into three packages: net.mednikov.teststutorial.groupA, net.mednikov.teststutorial.groupA, net.mednikov.teststutorial.groupC respectively. We can write the test suite to combine them:

@RunWith(JUnitPlatform.class)
@SelectPackages({net.mednikov.teststutorial.groupA, net.mednikov.teststutorial.groupB, net.mednikov.teststutorial.groupC})
public class TestSuite(){}

Now, you can run this method as one test suite.

References

  • Sergio Martin. Take Unit Testing to the Next Level With JUnit 5 (2018). DZone, read here
  • Petri Kainulainen. Writing Assertions with JUnit5 Assertion API (2018), read here
  • J Steven Perry. The JUnit5 Jupiter API (2017) IBM Developer, read here

Conclusion

In this post, we learned what is unit test and why to test; how to install JUnit 5 in your project; what is a basic test structure; how to use Asseritions API and how to combine multiple tests from different packages in a test suite. But, of course, JUnit 5 is a huge topic, and this post is just a top of an iceberg. Some frameworks, like Vert.x, offer special JUnit 5 extensions, like vertx-junit5. Good luck with JUnit5 ! :)

Originally published by YURI MEDNIKOV at mednikov.net 

=====================================================================

Thanks for reading :heart: If you liked this post, share it with all of your programming buddies! Follow me on Facebook | Twitter

☞ Java Programming Masterclass for Software Developers

☞ JSP, Servlets and JDBC for Beginners: Build a Database App

☞ Java 8 New Features In Simple Way

☞ Java In-Depth: Become a Complete Java Engineer!

☞ Java for Absolute Beginners

☞ Java Programming for Complete Beginners - Learn in 250 Steps

☞ Learn Java Programming Crash Course

☞ Apache Spark for Java Developers

#java #web-development

What is GEEK

Buddha Community

How to start with unit testing in Java: A complete introduction to JUnit 5
Joseph  Murray

Joseph Murray

1621492530

7 Test Frameworks To Follow in 2021 for Java/Fullstack Developers

It is time to learn new test frameworks in 2021 to improve your code quality and decrease the time of your testing phase. Let’s explore 6 options for devs.

It is time to learn new test frameworks to improve your code quality and decrease the time of your testing phase. I have selected six testing frameworks that sound promising. Some have existed for quite a long time but I have not heard about them before.

At the end of the article, please tell me what you think about them and what your favorite ones are.

Robot Framework

Robot Framework is a generic open-source automation framework. It can be used for test automation and robotic process automation (RPA).

Robot Framework is open and extensible and can be integrated with virtually any other tool to create powerful and flexible automation solutions. Being open-source also means that Robot Framework is free to use without licensing costs.

The RoboFramework is a framework** to write test cases and automation processes.** It means that it may replace** your classic combo Selenium + Cucumber + Gherkins**. To be more precise, the Cucumber Gherkins custom implementation you wrote will be handled by RoboFramework and Selenium invoked below.

For the Java developers, this framework can be executed with Maven or Gradle (but less mature for the latter solution).

#java #testing #test #java framework #java frameworks #testing and developing #java testing #robot framework #test framework #2021

Tyrique  Littel

Tyrique Littel

1600135200

How to Install OpenJDK 11 on CentOS 8

What is OpenJDK?

OpenJDk or Open Java Development Kit is a free, open-source framework of the Java Platform, Standard Edition (or Java SE). It contains the virtual machine, the Java Class Library, and the Java compiler. The difference between the Oracle OpenJDK and Oracle JDK is that OpenJDK is a source code reference point for the open-source model. Simultaneously, the Oracle JDK is a continuation or advanced model of the OpenJDK, which is not open source and requires a license to use.

In this article, we will be installing OpenJDK on Centos 8.

#tutorials #alternatives #centos #centos 8 #configuration #dnf #frameworks #java #java development kit #java ee #java environment variables #java framework #java jdk #java jre #java platform #java sdk #java se #jdk #jre #open java development kit #open source #openjdk #openjdk 11 #openjdk 8 #openjdk runtime environment

Were  Joyce

Were Joyce

1624374660

Java Unit Tests make easy — Random Values with PODAM

In this article Java Unit Tests make easy — Random Values with PODAM, we discuss how to generate random values to object, collections we use on Junit test using PODAM library

hen we write unit test cases for functions, a big headache for developers is filling mock data to our objects, collections etc.

For example, let see what would be the test case to fetch an object from a function.

Please look below code snippet. In this object contains the list of child objects too.

In this code snippet, we can see a lot of hardcode data we have to use to fill the object with values.

Now let see what we can do for this matter…

Any good solution??

Yes, we have PODAM.

#spring-boot #java #junit #podam #java unit tests make easy — random values with podam #java unit tests

Software Testing 101: Regression Tests, Unit Tests, Integration Tests

Automation and segregation can help you build better software
If you write automated tests and deliver them to the customer, he can make sure the software is working properly. And, at the end of the day, he paid for it.

Ok. We can segregate or separate the tests according to some criteria. For example, “white box” tests are used to measure the internal quality of the software, in addition to the expected results. They are very useful to know the percentage of lines of code executed, the cyclomatic complexity and several other software metrics. Unit tests are white box tests.

#testing #software testing #regression tests #unit tests #integration tests

Samanta  Moore

Samanta Moore

1620458875

Going Beyond Java 8: Local Variable Type Inference (var) - DZone Java

According to some surveys, such as JetBrains’s great survey, Java 8 is currently the most used version of Java, despite being a 2014 release.

What you are reading is one in a series of articles titled ‘Going beyond Java 8,’ inspired by the contents of my book, Java for Aliens. These articles will guide you step-by-step through the most important features introduced to the language, starting from version 9. The aim is to make you aware of how important it is to move forward from Java 8, explaining the enormous advantages that the latest versions of the language offer.

In this article, we will talk about the most important new feature introduced with Java 10. Officially called local variable type inference, this feature is better known as the **introduction of the word **var. Despite the complicated name, it is actually quite a simple feature to use. However, some observations need to be made before we can see the impact that the introduction of the word var has on other pre-existing characteristics.

#java #java 11 #java 10 #java 12 #var #java 14 #java 13 #java 15 #verbosity