DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workkloads.

Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • 6 of the Best API Testing Tools in the Market
  • Thread-Safety Pitfalls in XML Processing
  • Java Stream API: 3 Things Every Developer Should Know About
  • Mastering Unit Testing and Test-Driven Development in Java

Trending

  • Rethinking Recruitment: A Journey Through Hiring Practices
  • While Performing Dependency Selection, I Avoid the Loss Of Sleep From Node.js Libraries' Dangers
  • Mastering Fluent Bit: Installing and Configuring Fluent Bit on Kubernetes (Part 3)
  • A Modern Stack for Building Scalable Systems
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. DevOps and CI/CD
  4. Unit Testing: Java Streams and Lambdas

Unit Testing: Java Streams and Lambdas

While Java streams and lambdas can seem complex for unit testing, this tutorial demonstrates simplified instructions to perform unit testing in JDK8.

By 
Yogen Rai user avatar
Yogen Rai
·
Manoj Debnath user avatar
Manoj Debnath
·
Updated Jan. 26, 24 · Tutorial
Likes (21)
Comment
Save
Tweet
Share
98.5K Views

Join the DZone community and get the full member experience.

Join For Free

Unit testing is an indispensable practice for Java developers (any developer really). The primary benefit of unit testing a pipeline is the early detection of bugs, which is less expensive to fix. It not only improves the overall quality of the code but also makes future maintenance easy.

Using lambdas specifically with streams in Java makes code concise and readable. Streams are excellent for filtering, mapping, sorting, and reducing operations. The elements in the sequence are better processed in a declarative and functional manner, something which lambdas exactly fit into. The anonymous functions that are written with lambdas not only facilitate a functional style of programming but also enhance the expressiveness of the code. Streams and lambdas were introduced in Java after JDK 8, and since then, Java developers have used these features frequently in their projects.

The question around these components that the article tries to address is, "How can you unit test Java streams and lambdas?"

Importance of Unit Testing Pipelines and Lambdas

In unit testing, an individual piece of component of a software application is tested separately. This small unit of code typically is a function, method, or subroutine. The testing mechanism is automated so that they can be done repeatedly and quickly. The test cases are usually written by developers and integrated into the CI/CD pipeline in the development process. The code can be isolated and problems can be easily identified if we use lambda because the essence of it is to make the program functional, more modular, and reusable — something which makes it friendly for unit testing pipelines.

Unit Testing Stream Pipelines

Since stream pipelines combine with lambdas to form a single unit, it is not obvious how to effectively unit test the pieces of the pipeline. 

I have always followed these two guidelines to unit test those stream pipelines:

  1. If the pipeline is simple enough, it can be wrapped in a method call, and it is enough to unit test the method call.
  2. If the pipeline is more complex, pieces of the pipeline can be called from support methods, and the support methods can be unit-tested.

For example, let's say we have a stream pipeline that maps all the letters of the word to uppercase and is wrapped in a java.util.function.Function<T,R>  as below:

Function<List<String>, List<String>> allToUpperCase = words -> words.stream().map(String::toUpperCase).collect(Collectors.toList());


Now, the unit test for this stream pipeline can be easily written as ordinary unit testing of the allToUpperCase.

@Test
public void testAllToUpperCase() {    
  List<String> expected = Arrays.asList("JAVA8", "STREAMS");    
  List<String> result = allToUpperCase.apply(Arrays.asList("java8", "streams"));    
  assertEquals(expected, result);
}


The stream above can be wrapped in a regular function, as seen below. Also, an ordinary unit test can be written against this function:

public List<String> convertAllToUpperCase(List<String> words) {    
  return words.stream().map(String::toUpperCase).collect(Collectors.toList());
}


Unit Testing Lambdas

Believe me — it is very likely that you will encounter complex unit testing in real-world programming. The unit testing with complex lambdas, similar to unit testing of stream pipelines, can be simplified with the following practices:

  1. Replace a lambda that needs to be tested with a method reference and an auxiliary method.
  2. Then, test the auxiliary method.

For example, I have a stream pipeline that involves a somewhat complex lambda and a mapping class for the given string class name.

public static Class[] mapClasses(final List<String> exceptions) {    
  return exceptions.stream().map(className -> {        
    try {            
      return Class.forName(className);        
    } catch(Exception ex) {            
      LOGGER.error("Failed to load class for exceptionWhiteList: {}", className);        
    }        
    return null;    
  }).toArray(Class[]::new);
}


Here, the key point to test is whether the expression for transforming a string class name to a Class object is working.

As mentioned above, this can replace the lambda expression with a method reference, along with an auxiliary method that can be placed in a companion class, as shown below:

public static Class[] mapClassesBetter(final List<String> exceptions) {    
  return exceptions.stream().map(LambdaTester::mapClass).toArray(Class[]::new);
}

public static Class mapClass(String className) {    
  try {        
    return Class.forName(className);    
  } catch(Exception ex) {        
    LOGGER.error("Failed to load class for name: {}", className);    
  }    
  return null;
}


Now, the key element of the original lambda is that it can be tested directly:

@Test
public void testMapClass() throws ClassNotFoundException {    
  assertEquals(null, mapClass("a"));    
  assertEquals(null, mapClass("apple"));    
  assertEquals(Object.class, mapClass("java.lang.Object"));
}


Conclusion

Writing unit tests is one of the core parts of software development.  With new features introduced after JDK 8, it has become easier to write code concisely and declaratively. However, the proper use of features like streams and lambda brings value and, of course, makes writing unit tests easier. If you have any additional guidelines for unit testing these features, don't stop yourself from sharing them in the comments. Until next time, happy coding! Learn more about the best Java unit testing frameworks.

The source code for the examples presented above is available on GitHub.

unit test Stream (computing) Java (programming language) Continuous Integration/Deployment

Opinions expressed by DZone contributors are their own.

Related

  • 6 of the Best API Testing Tools in the Market
  • Thread-Safety Pitfalls in XML Processing
  • Java Stream API: 3 Things Every Developer Should Know About
  • Mastering Unit Testing and Test-Driven Development in Java

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!