Best Java Unit Testing Frameworks You Must Know In 2019

Best Java Unit Testing Frameworks You Must Know In 2019

Unit testing is an important skill for programmers. With that said, what are the best frameworks you can use to write great unit tests in Java?

Originally published by Ranga Karanam at https://dzone.com
What We Will Learn
  • What are the best Java unit testing frameworks?
  • What is JUnit? How do you use JUnit for unit testing?
  • What is Mockito?
  • What is mocking?
  • How do you write unit tests with Junit, Mockito, AssertJ, and other frameworks?
  • What is the best Java unit testing framework for writing great asserts?
The Base Unit Testing Framework — JUnit/TestNG

Whenever you write a unit test, you execute the code and then check its output. You need a basic framework in place to run a large number of tests in a similar manner.

JUnit

The JUnit framework provides a basic framework that allows you to specify the test that you want to run, along with its inputs, and the result that comes out of it.

Have a look at the following test:

@Test
public truncateAInFirst2Positions_AinFirstPosition() {
assertEquals("CD", helper.truncateAInFirstPosition("ACD"));
}

Notice the annotation @Test used the decorate the test. The name of the test is descriptive and demonstrates the intent of the test. JUnit provides different kinds of assertion methods to check the result of the code executed within a test. These include assertEquals(), assertTrue(), and assertFalse().

Now have a look at this one that tests a negative scenario:

@Test
public testAreFirstAndLastTwoCharactersTheSame_BasicNegativeScenario() {
assertFalse(helper.areFirstAndLastTwoCharactersTheSame("ABCD"));
}

JUnit also supports something called parameterized tests.

TestNG

TestNG is a good alternative to JUnit to write unit tests and makes it easy to write customized tests. Suppose you have the test data needed to execute your suites in a spreadsheet or an XML document. TestNG makes it easy to get the data for tests to be written around them.

At a high level, JUnit and TestNG are frameworks that enable you to write tests and check results. If a test succeeds, you see a green bar. Or else, a red bar.

Mocking Frameworks — Mockito and EasyMock

When writing unit tests, it is often required to mock or stub dependencies.

Mocking is preferred to stubbing. There are a couple of great options for mocking in the Java world — Mockito and EasyMock.

Mockito

Have a look at the following example:

public class SomeBusinessImpl {
private DataService dataService;
//Constructor - public SomeBusinessImpl(DataService dataService) { //... }
int findTheGreatestFromAllData() {
int[] data = dataService.retrieveAllData();
int greatest = Integer.MIN_VALUE;
for (int value : data) {
if(value > greatest)
greatest = value;
}
return greatest;
}
}

The value returned by the findTheGreatestFromAllData() depends on the data that comes back from the data service.

To be able to write a good unit test for this method, you need to mock this dependency out.

Have a look at the following test for the class:

@Test
public void testFindTheGreatestFromAllData() {
DataService dataServiceMock = mock(DataService.class);
when(dataServiceMock.retrieveAllData())
.thenReturn(new int[] {24, 15, 3});
SomeBusinessImpl businessImpl = new SomeBusinessImpl(dataServiceMock);
int result = businessImpl.returnTheGreatestFromAllData();
assertEquals(24, result);
}

Mockito makes it easy to mock the DataService. Here, we use its mock() method to mock the DataService and inject the mock into the SomeBusinessImpl class.

Mockito also provides great annotations to inject mocks automatically.

@RunWith(MockitoJUNitRunner.class)
public class SomeBusinessMockAnnotationsTest {
@Mock
DataService dataServiceMock;
@InjectMocks
SomeBusinessImpl businessImpl;
@Test
public void testFindTheGreatesFromAllData() {
when(dataServiceMock.retrieveAllData())
.thenReturn(new int[] {24, 15, 3});
assertEquals(24, businessImpl.findTheGreatestFromAllData());
}
}

Annotations such as @Mock and @InjectMocks take care of what their names suggest, thereby making the test code smaller and more readable.

EasyMock

EasyMock is also a mocking framework that can be effectively used in unit tests. It is a popular alternative to Mockito.

Mocking Complex Scenarios — Use PowerMock

Frameworks such as Mockito allow you to insert mocks only when the code design is good. When the design is not so good, PowerMock comes to your rescue.

Powermock is useful when you want to mock static methods, constructors, and private methods.

Have a look at the following code:

interface Dependency {
List<Integer> retrieveAllStats();
}
public class SystemUnderTest {
private Dependency dependency;
public int methodUsingAnArrayListConstructor() {
ArrayList list = new ArrayList();
return list.size();
}
public int methodCallingAStaticMethod() {
//private methodUnderTest calls static method SomeClass.staticMethod
List<Integer> stats = dependency.retrieveAllStats();
long sum = 0;
for(int stat : stats) {
sum += stat;
}
return UtilityClass.staticMethod(sum);
}
private long privateMethodUnderTest() {
List<Integer> stats = dependency.retrieveAllStats();
long sum = 0;
for(int stat : stats) {
sum += stat;
}
return sum;
}
}

Here, SomeClass.staticMethod is a static method that is defined. Therefore, we have a need to mock it out. We need to test the method methodCallingAStaticMethod() after this mock. Have a look at the following test code:

@RunWith(PowerMockRunner.class)
@PrepareForTest({UtilityClass.class})
public class PowerMockitoMockingStaticMethodTest {
@Mock
Dependency dependencyMock;
@InjectMocks
SystemUnderTest systemUnderTest;
@Test
public void powerMockito_MockingAStaticMethodCall() {
when(dependencyMock.retrieveAllStats()).thenReturn(Arrays.asList({1, 2, 3}));
PowerMockito.mockStatic(UtilityClass.class);
when(UtilityClass.staticMethod(anyLong())).thenReturn(150);
assertEquals(150, systemUnderTest.methodCallingAStaticMethod);
//Verify the specific method call
//First, call PowerMockito.verifyStatic()
//Second, call the method to be verified
PowerMockito.verifyStatic(); 
UtilityClass.staticMethod(1 + 2 + 3);
//verify exact number of calls
//PowerMockito.verifyStatic(Mockito.times(1));
}
}

Here, we have written code that allows us to mock out a static method.

It is also possible to mock a constructor:

@RunWith(PowerMockRunner.class)
@PrepareForTest({UtilityClass.class})
public class PowerMockitoMockingConstructorTest {
private static final int SOME_DUMMY_SIZE = 100;
@Mock
Dependency dependencyMock;
@InjectMocks
SystemUnderTest systemUnderTest;
@Test
public void powerMockito_MockingAConstructor throws Exception {
ArrayList<String> mockList = mock(ArrayList.class);
stub(mockList.size()).toReturn(SOME_DUMMY_SIZE);
PowerMockito.whenNew(ArrayLst.class).withAnyArguments().thenReturn(mockList);
int size = systemUnderTest.methodUsingAnArrayListConstructor();
assertEquals(SOME_DUMMY_SIZE, size);
}
}

When the constructor is called, the mockList is returned instead.

PowerMock can also be used to mock private methods:

@RunWith(PowerMockRunner.class)
@PrepareForTest({UtilityClass.class})
public class PowerMockitoMockingPrivateMethodTest {
@Mock
Dependency dependencyMock;
@InjectMocks
SystemUnderTest systemUnderTest;
@Test
public void powerMockito_CallingAPrivateMethod throws Exception {
when(dependencyMock.retrieveAllStats()).thenReturn(Arrays.asList({1, 2, 3}));
long value = (Long) WhiteBox.invokeMethod(systemUnderTest,
"PrivateMethodUnderTest");
assertEquals(6, value);
}

Note that you cannot directly invoke a private method from test code. We are using the functionality of a class named WhiteBox, to which we pass the string name of the private method.

Writing Great Asserts Using AssertJ/Hamcrest

Whenever you write tests, you want to have great assertions.

AssertJ

Have a look at the folowing code:

public class AssertJTest {
@Test
public void learning() {
List<Integers> numbers = Arrays.asList({12, 15, 45});
assertThat(numbers).hasSize(3)
.contains(12, 15)
.allMatch(x -> x > 10)
.allMatch(x -> x < 100)
.noneMatch(x -> x < 0);
assertThat("").isEmpty;
assertThat("ABCDE").contains("BCD")
.startsWith("ABC")
.endsWith(""CDE);
}
}

numbers is a list of integers that contains 3 values as shown. AssertJ provides the method assertThat(), which allows you to chain together multiple assertions.

Interestingly, you can see that the method allMatch() accepts a lambda expression to test the truth value of a predicate. The call allMatch(x -> x > 10) checks whether all the integers within numbers match the predicate of being greater than 10.

assertThat() also works with strings, and works well especially with alphabetical text. The code is there for you to see.

Hamcrest

Hamcrest provides an alternative to AssertJ to write great asserts.

public class HamcrestMatchersTest {
public void learning() {
List<Integer> numbers = Arrays.asList({12, 15, 45});
assertThat(numbers, hasSize(3));
assertThat(numbers, hasItems(12, 15));
assertThat(numbers, everyItem(greaterThan(10)));
assertThat(numbers, everyItem(lessThan(100)));
assertThat("", isEmptyString());
assertThat("ABCDE", containsString("BCD"));
assertThat("ABCDE", startsWith("ABC"));
assertThat("ABCDE", endsWith("CDE"));
}
}
Using Spring Unit

Typical applications have multiple layers and you want to write unit tests for different layers — web, business, and data.

Here are some of the recommended options:

  • Web layer — Spring MockMVC
  • Data layer — DataJpaTest
  • Business layer — Mockito-based test preferably without launching a Spring Context

Unit Tests for the Web Layer

Have a look at the following code:

@RunWith(SpringRunner.class)
@WebMvcTest(ItemController.class)
public class ItemControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private ItemBusinessService businessService;
@test
public void dummyItem_basic throws Exception {
RequestBuilder request = MockMvcRequestBuilders
.get("/dummy-item")
.accept(MediaType.APPLICATION_JSON);
MvcResult result = mockMvc.perform(request)
.andExpect(status().isOk())
.andExpect(content()
.json("{\"id\":1, \"name\":\"Ball\"
, \"price\":10, \"quantity\":5}"))
.andReturn();
//JSONAssert.assertEquals(expected, result.getResponse.getContentAsString(), flase);
}
}

This unit test uses the Spring Unit framework and the Spring MockMVC framework.

We are launching a Spring context and wiring ItemController to use a mock for ItemBusinessService.

Spring MockMVC framework makes it easy to perform REST API requests. In the code above, we are using it to execute a REST API and then setting certain expectations of the result:

  • The URL is /dummy-item
  • The accepted content type is application+json
  • After the request has been sent, check that the response status is "OK", and the content is a JSON object with certain data

It is also possible for us to mock the business service:

@Test
public void retrieveAllItems_basic() throws Exception {
when(businessService.retrieveAllItems()).thenReturn(
Arrays.asList(new Item(2, "Item2", 10, 10)
, new Item(3, "Item3", 20, 20)));
RequestBuilder request = MockMvcRequestBuilders
.get("/all-items-from-database")
.accept(MediaType.APPLICATION_JSON);
MvcResult result = mockMvc.perform(request)
.andExpect(status().isOk())
.andExpect(content()
.json("[{\"id\":3, \"name\":\"Item3\"
, \"price\":20}]"))
,{\"id\":2, \"name\":\"Item2\"
, \"price\":10}]")
.andReturn();
}

When retrieveAllItems() is called on businessService, it is made to return the fixed list of items shown. Once again, we execute a request to a different URL, and when the response comes in, the content is verified to be the proper JSON type with the expected data.

Unit Tests for the Data Layer

DataJpaTest can be used during unit testing of the data layer in a Spring-based enterprise application. DataJpaTest uses an in-memory database for the unit test, by default.

@RunWith(SpringRunner.class)
@DataJpaTest
public class ItemRepositoryTest {
@Autowired
private ItemRepository repository;
@Test
public void testFindAll() {
List<Item> items = repository.findAll();
assertEquals(3, items.size());
}
@Test
public void testFindOne() {
Item item = repository.findById(10001).get();
assertEquals("Item1", item.getName());
}
}
Asserting JSON Responses — JSONAssert/JSONPath

Almost all REST APIs use JSON. How do you assert JSON Content?

Using JSONAssert

Have a look at the following test code:

actualResponse is the content that is returned by a service.

JSONAssert allows us to check specific parts of the request that we are interested in.

  • Within the test jsonAssert_StrictFalse(), we are only concerned with the id, name, and price, ignoring the quantity.
  • You can also write a test to check without escape characters, as we have done with jsonAssert_WithoutEscapeCharacters(). This is much easier on the eye and can be used to compare with an actual response that contains escape characters. This mode of comparing responses is called Strict False.

You can also do assertions in Strict mode, where you compare all the fields, and in the actual format, they are in. That is what we have done with jsonAssert_StrictFalse_ExactMatchExceptForSpaces().

Using JSONPath

An alternative approach in asserting JSONs is the JSONPath framework. You might want to check for specific aspects of the response, such as three items in the response.

Just as XPath is used to query XML, JSONPath is used to query JSON.

  • The expression $.length() returns the number of elements. An assertion can then be used on that returned value.
  • You can check for all the id fields with $..id and compare them with a list of pre-fixed values.
  • You can extract slices of the element list that is in the response, such as the first element ($.[1]), or the first 2 elements ($.[0:2]).
  • You can query the response to check if a particular field is present : $.[?(@.name == 'Eraser')] or $.[?(@.quantity == 5)].
Summary

In this article, we looked at a wide variety of unit testing frameworks present in the Java world. We started with the basic unit testing framework JUnit, and its alternative, TestNG. We looked at how we can do mocking with Mockito and its alternative, EasyMock. We then had a look at Powermock, which is useful when mocking static methods, private methods, and constructors.

We then had a feel of powerful assertion frameworks such as AsserJ and Hamcrest. Spring Unit framework provides MockMVC as the mocking framework for the web layer and DataJPATest for the data layer. Finally, we explored JSONAssert and JSONPath used to assert JSON responses in a unit test.

Thanks for reading

If you liked this post, share it with all of your programming buddies!

Follow us on Facebook | Twitter

Further reading

JavaScript and Node.js Testing Best Practices

An Introduction to Unit Testing in Angular

How to set up and run visual testing with Percy


Angular 9 Tutorial: Learn to Build a CRUD Angular App Quickly

What's new in Bootstrap 5 and when Bootstrap 5 release date?

What’s new in HTML6

How to Build Progressive Web Apps (PWA) using Angular 9

What is new features in Javascript ES2020 ECMAScript 2020

Test a REST API with Java

Test a REST API with Java

This tutorial focuses on the basic principles and mechanics of testing a REST API with live Integration Tests (with a JSON payload).

This tutorial focuses on the basic principles and mechanics of testing a REST API with live Integration Tests (with a JSON payload).

1. Overview

The main goal is to provide an introduction to testing the basic correctness of the API – and we’re going to be using the latest version of the GitHub REST API for the examples.

For an internal application, this kind of testing will usually run as a late step in a Continuous Integration process, consuming the REST API after it has already been deployed.

When testing a REST resource, there are usually a few orthogonal responsibilities the tests should focus on:

  • the HTTP response code
  • other HTTP headers in the response
  • the payload (JSON, XML)

Each test should only focus on a single responsibility and include a single assertion. Focusing on a clear separation always has benefits, but when doing this kind of black box testing is even more important, as the general tendency is to write complex test scenarios in the very beginning.

Another important aspect of the integration tests is adherence to the Single Level of Abstraction Principle – the logic within a test should be written at a high level. Details such as creating the request, sending the HTTP request to the server, dealing with IO, etc should not be done inline but via utility methods.

2. Testing the Status Code
@Test
public void givenUserDoesNotExists_whenUserInfoIsRetrieved_then404IsReceived()
  throws ClientProtocolException, IOException {
  
    // Given
    String name = RandomStringUtils.randomAlphabetic( 8 );
    HttpUriRequest request = new HttpGet( "https://api.github.com/users/" + name );
 
    // When
    HttpResponse httpResponse = HttpClientBuilder.create().build().execute( request );
 
    // Then
    assertThat(
      httpResponse.getStatusLine().getStatusCode(),
      equalTo(HttpStatus.SC_NOT_FOUND));
}

This is a rather simple test – it verifies that a basic happy path is working, without adding too much complexity to the test suite.

If for whatever reason, it fails, then there is no need to look at any other test for this URL until this is fixed.

3. Testing the Media Type
@Test
public void
givenRequestWithNoAcceptHeader_whenRequestIsExecuted_thenDefaultResponseContentTypeIsJson()
  throws ClientProtocolException, IOException {
  
   // Given
   String jsonMimeType = "application/json";
   HttpUriRequest request = new HttpGet( "https://api.github.com/users/eugenp" );
 
   // When
   HttpResponse response = HttpClientBuilder.create().build().execute( request );
 
   // Then
   String mimeType = ContentType.getOrDefault(response.getEntity()).getMimeType();
   assertEquals( jsonMimeType, mimeType );
}

This ensures that the Response actually contains JSON data.

As you might have noticed, we’re following a logical progression of tests – first the Response Status Code (to ensure that the request was OK), then the Media Type of the Response, and only in the next test will we look at the actual JSON payload.

4. Testing the JSON Payload
@Test
public void
  givenUserExists_whenUserInformationIsRetrieved_thenRetrievedResourceIsCorrect()
  throws ClientProtocolException, IOException {
  
    // Given
    HttpUriRequest request = new HttpGet( "https://api.github.com/users/eugenp" );
 
    // When
    HttpResponse response = HttpClientBuilder.create().build().execute( request );
 
    // Then
    GitHubUser resource = RetrieveUtil.retrieveResourceFromResponse(
      response, GitHubUser.class);
    assertThat( "eugenp", Matchers.is( resource.getLogin() ) );
}

In this case, I know the default representation of GitHub resources is JSON, but usually, the Content-Type header of the response should be tested alongside the Accept header of the request – the client asks for a particular type of representation via Accept, which the server should honor.

5. Utilities for Testing

We’re going to use Jackson 2 to unmarshall the raw JSON String into a type-safe Java Entity:

public class GitHubUser {
 
    private String login;
 
    // standard getters and setters
}

We’re only using a simple utility to keep the tests clean, readable and at a high level of abstraction:

public static <T> T retrieveResourceFromResponse(HttpResponse response, Class<T> clazz)
  throws IOException {
  
    String jsonFromResponse = EntityUtils.toString(response.getEntity());
    ObjectMapper mapper = new ObjectMapper()
      .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    return mapper.readValue(jsonFromResponse, clazz);
}

Notice that Jackson is ignoring unknown properties that the GitHub API is sending our way – that’s simply because the Representation of a User Resource on GitHub gets pretty complex – and we don’t need any of that information here.

6. Dependencies

The utilities and tests make use of the following libraries, all available in Maven central:

7. Conclusion

This is only one part of what the complete integration testing suite should be. The tests focus on ensuring basic correctness for the REST API, without going into more complex scenarios,

For example, the following are not covered: Discoverability of the API, consumption of different representations for the same Resource, etc.

The implementation of all these examples and code snippets can be found over on Github – this is a Maven-based project, so it should be easy to import and run as it is.

Java Essentials : Learn Core Java From Basic to Advance

Java Essentials : Learn Core Java From Basic to Advance

Learn Java Programming Using Practical Assignments. Start Building Back-end Web Applications Robust Test Automation Frameworks By End Of The Course. Learn More!

Description
This is only Java related course and it's great because it covers just the right amount of Java which is needed to leaning programming, java.

This is a comprehensive yet simple course on java programming language and it concentrates on Java programming concepts.

*************************** No Prior Coding Experience Needed ***************************

This course assumes that you have no programming background. If you have some experience then, it's just a bonus point. You have never code, have some experience or have a lot of experience any other programming language, this course is one stop place for you.

Java is one of the most and useful programming languages to learn You can build back-end of web applications and build robust test automation framework. Specially for Selenium WebDriver GUI automation, Java is most popular choice and has the largest community.

Each lecture consist of a video screencast and code files

There are quizzes, homework to test your knowledge

High focus on practice and asking questions

You will also learn coding best practices

Market is never short of jobs in Java programming language, there are ample of jobs in both Java development and Automation Testing using Java.

What are you waiting for? Enroll today and learn the powerful Java language !!!

Basic knowledge
Nothing else! It’s just you, your computer and your hunger to get started today
Java concepts are covered in the course, no experience needed
Windows/MAC computer
What will you learn
You will be able to EXPLAIN, DESIGN and IMPLEMENT efficient java Programs
You will be confident to clear test automation interviews
Understand the concepts of Object Oriented Programming Language
Complete understanding of java
Expert-level knowledge of Java code (+ advanced tips and tricks used by the pros)
Suitable for beginner programmers and ideal for users who learn faster when shown
To learn more:

Java Fundamentals: Learn Java for absolute beginners |Simpliv

Java Fundamentals: Learn Java for absolute beginners |Simpliv

Java Fundamentals: Learn Java for absolute beginners

Description
This is the best course to learn to program in Java in Spanish from scratch and without any experience in this fabulous programming language. This is the first course where we will study the Fundamentals of Java, and we will take you step by step until you acquire the bases of the Java language and you can start to study more advanced Java topics.

The content is divided into perfectly structured levels, each level supported by the previous one, with the aim of adding Java knowledge incrementally and so you can focus on mastering the issues little by little and gradually. So ensure the success of your Java training.

We will also offer support for any doubts about the didactic material included in this Java Fundamentals course.

We manage a new teaching methodology that we have called Speed ​​Learning. This methodology consists of concise videos that go directly to the point to be studied, complemented by eBooks with explanations and step-by-step images (which you can print, or search for any text you need, or use for your offline study), since As we know we can not do text search within a video. In addition, our methodology includes perfectly structured and very didactic exercises that will allow you to accelerate your eLearning learning. No loss of time in videos where you have to watch the instructor codify an exercise, too much theory, little practice or anything like that. Our Speed ​​Learning methodology guarantees that in the shortest possible time you will acquire the necessary knowledge for the Java professional and working world.

The Java Fundamentals course includes the following topics for study:

Lesson 1 - Starting with Java Technology

The amazing world of Java programming

What is Java technology (from a practical approach)

Our first Java program from scratch

Lesson 2 - Variables and Operators in Java

Use of Variables in Java and what we use them for

Types of Data in Java and how they are classified

Management and Classification of operators in Java

Lesson 3 - Control statements in Java

Using the if-else structure and where to use it

Handling the switch structure and when applying it

Lesson 4 - Handling Loops in Java

Use of the for loop and its use

Using the while loop and how to apply it

Use of the do-while loop and when to use it

Lesson 5 - Object Oriented Programming

Introduction to Object Oriented Programming (OOP)

Handling Classes in Java

Use of Objects in Java

Lesson 6 - Functions in Java

Declaration of Methods or Functions in Java

Use and call of functions in Java

Lesson 7 - Data Management in Java

Using Arrays in Java

Management of Matrices in Java

Lesson 8 - Inheritance in Java

Inheritance Management in Java

Use of superclasses and subclasses in Java

Final Level Laboratory

Final Exercise where everything learned in this Level is integrated

At the end you get a certificate of having completed the Java Fundamentals course.

We wait for you on the other side.

Ing. Ubaldo Acosta

Founder of Global Mentoring

Passion for Java Technology

Who this course is for:

Anyone who wants to learn how to program in Java
Basic knowledge
Basic knowledge of PC use
Basic management of an operating system such as Windows, Mac or Linux
It is not necessary to know how to program, we will start from scratch !!!
The attitude and desire to start coding and learning Java once and for all from scratch!
What will you learn
Have the basics of the programming language with Java
You will know the basic syntax of the Java language
Manage the concept of Variables and Operators in Java
We will study Object Oriented Programming with Java
You will learn the Control Statements and Loops in Java
We will see the concept of Functions with Java
We will study the concept of Inheritance in Java
We will learn to use Arrays in java
We will handle the concept of Matrices in Java
We will learn to Design Classes in Java
We will make a final application with everything learned in the course
To know more: