Java

Unit Testing Lambda Expressions & Streams

Richard Warburton

This is a guest post from Richard Warburton, who has worked as a developer across varied areas including Statistical Analytics, Static Analysis, Compilers and Networking. He is a leader in the London Java Community and runs OpenJDK Hackdays.

Richard also teaches a course on modern development with Java 8 at Skills Matter, alongside Jim Gough & Raoul-Gabriel Urma. At the end of this course, you will be ready to use Java 8 on your day job and be familiar with the cutting edge programming approaches which allow you to write more flexible and concise code. You can find out more information about the course here, or head to the Skills Matter page to book your place now!


Usually, when writing a unit test you call a method in your test code that gets called in your application. Given some inputs and possibly test doubles, you call these methods to test a certain behavior happening and then specify the changes you expect to result from this behavior.

Lambda expressions pose a slightly different challenge when unit testing code. Because they don’t have a name, it’s impossible to directly call them in your test code. You could choose to copy the body of the lambda expression into your test and then test that copy, but this approach has the unfortunate side effect of not actually testing the behavior of your implementation. If you change the implementation code, your test will still pass even though the implementation is performing a different task.

There are two viable solutions to this problem. The first is to view the lambda expression as a block of code within its surrounding method. If you take this approach, you should be testing the behavior of the surrounding method, not the lambda expression itself.

Here’s an example method for converting a list of strings into their uppercase equivalents.

public static List allToUpperCase(List words) {
    return words.stream()
                .map(string -> string.toUpperCase())
                .collect(Collectors.toList());
}

The only thing that the lambda expression in this body of code does is directly call a core Java method. It’s really not worth the effort of testing this lambda expression as an independent unit of code at all, since the behavior is so simple.

If I were to unit test this code, I would focus on the behavior of the method. For example, here is a test that if there are multiple words in the stream, they are all converted to their uppercase equivalents.

@Test
public void multipleWordsToUppercase() {
    List input = Arrays.asList("a", "b", "hello");
    List result = allToUpperCase(input);
    assertEquals(asList("A", "B", "HELLO"), result);
}

Sometimes you want to use a lambda expression that exhibits complex functionality. Perhaps it has a number of corner cases or a role involving calculating a highly important function in your domain. You really want to test for behavior specific to that body of code, but it’s in a lambda expression and you’ve got no way of referencing it.

As an example problem, let’s look at a method that is slightly more complex than converting a list of strings to uppercase. Instead, we’ll be converting the first character of a string to uppercase and leaving the rest as is. If we were to write this using streams and lambda expressions, we might write something like the following.

public static List uppercaseFirstChar(List words) {
    return words.stream()
                .map(value -> {
                    char firstChar = value.charAt(0);
    firstChar = toUpperCase(firstChar);
                    return firstChar + value.substring(1);
                })
                .collect(Collectors.toList());
}

Should we want to test this, we’d need to fire in a list and test the output for every single
example we wanted to test. The test below provides an example of how cumbersome this
approach becomes. Don’t worry—there is a solution!

@Test
public void twoLetterStringConvertedToUppercaseLambdas() {
    List input = Arrays.asList("ab");
    List result = uppercaseFirstChar(input);
    assertEquals(Arrays.asList("Ab"), result);
}

Don’t use a lambda expression! I know that might appear to be strange advice in an article about lambda expressions, but square pegs don’t fit into round holes very well. Having accepted this, we’re bound to ask how we can still unit test our code and have the benefit of lambda-enabled libraries.

Do use method references. Any method that would have been written as a lambda expression can also be written as a normal method and then directly referenced elsewhere in code using method references. In the code below I’ve refactored out the lambda expression into its own method. This is then used by the main method, which deals with converting the list of strings.

public static List uppercaseFirstChar(List words) {
    return words.stream()
                .map(Testing::firstToUppercase)
                .collect(Collectors.toList());
}

public static String firstToUppercase(String value) {
    char firstChar = value.charAt(0);
    firstChar = toUpperCase(firstChar);
    return firstChar + value.substring(1);
}

Having extracted the method that actually performs string processing, we can cover all the corner cases by testing that method on its own. The same test case in its new, simplified form is shown here:

@Test
public void twoLetterStringConvertedToUppercase() {
    String input = "ab";
    String result = firstToUppercase(input);
    assertEquals("Ab", result);
}

The key takeaway here is that if you want to unit test a lambda expression of serious complexity, extract it to a regular method first. You can then use method references to treat it like a first-class function.


This Week at Skills Matter: 11 – 15 August

this-week-blog-header


Monday:

How do you make Guacamole with Ruby? Dirk Breuer kicks off our week of meetups and with the London Ruby User Group telling you how. Well, not quite – the Guacamole is an ODM for ArangoDB which is used in Rack-based framework, especially Rails. Dirk will talk about the design choices, caveats and his own general experience working on that kind of library. The talk will not be overly technical, and both experts and novices are invited to join.

Joining Dirk, Alex Speller will discuss a gentle introduction to music theory as she shows how to start with nothing but a Ruby interpreter, and generate sine waves, notes, scales, modes, chords, arpeggios and songs, in a way that will be understandable to those who have never touched an instrument before. The talk promises to offer an interesting new perspective – even to those who are already well versed in music theory.

We’re also delighted to welcome Mauro Servienti for an In The Brain talk on designing distributed, scalable and reliable systems. Mauro Servienti, a RavenDB Contributor and CTO & Architect at Managed Designs, will start from the requirements that can drive us to scale and distribute a solution diving into the technical challenges and the obvious advantages that building a distributed and scalable solution brings to the table.

To find out a little bit more about Mauro, and for a quick sneak preview of his talk, be sure to check out the While It’s Compiling interview he did with us a couple of weeks ago.

Tuesday:

The two talks at the London Big-O meetup cover both Big Data and speech technology, as they’re joined by Tom Nielsen (founder of OpenBrain Ltd.) and Catherine Breslin (research engineer at Amazon).

Tom explores the Slow Fourier Transform, as he shows a simple Bayesian statistical model for which the posterior probability distribution is equivalent to the output of the Fourier transform. Come along to learn how this model can be implemented and run in probabilistic programming languages and to discuss some use cases in which it may be advantageous.

Catherine’s talk will focus on algorithms for audio segmentation and clustering, which allow us to answer the question – “Who spoke when?”. Looking at less well-known uses of speech technologies such as indexing audio and video archives (such as lectures, meetings or TV broadcasts), Catherine explores automatic transcription that allows people to search these far more easily than relying on meta data alone.

Infracoders London will be here to ask that you manage your clusters like you manage your machines, as Douglas Triggs (a self described code monkey for Chef) shows how Chef Metal allows you to repeatedly create machines and infrastructures in Chef the same way Chef allows you to repeatedly configure individual machines.

Wednesday:

Mean Stack join us on Wednesday for an evening of unit testing and responsive Javascript. First up Marton Hipszki will be looking at end-to-end unit testing as he takes us from setting up our environments to going down the testing pyramid. Travelling through writing tests, turning user stories to end-to-end tests and creating a solid backed API, byt the end you’ll discover how automated tests pay off.

JonathanFielding will then look at building better experiences with responsive Javascript as he goes beyond what CSS can offer, looking at new browser API’s that enable this, with the matchMedia API that can target specific functionality based on whether a media query matches.

Daniel Bryant and Abraham Marin-Perez join the London Java Community to discuss professional software development and the five shouts of good programmers. Want more information on Professional Software Development and what it takes to be a good programmer? Then join us for an evening with two fantastic speakers.

Thursday:

Rounding off the week, the F#unctional Londoners return, this week with Phil Nash to talk about Functional Scripting. In this session Phil will share with us how (and why) he has come to use F# as his preferred scripting language in place of more traditional options like Python. He’ll cover some practical examples and a few tips and techniques he’s picked up along the way – this talk is suitable for those new to F# and experienced users alike.

This Week at Skills Matter: 13th-17th January 2014

Last week we welcomed the London Java Community for our first two events of 2014! On Wednesday, Madhusudhan Konda explored what’s new in Java8 and Joshua Wöhle provided insight in how (quickly) a tech stack evolves in a start-up.

Gleb Smirnov talks at the London Java Community meetup, London

On Thursday the LJC returned with a talk from Gleb Smirnov on Mutation Analysis, in which he covered the available Java tools to do it, and shared a number of success stories.

This week we have five events, including a brand new user group! Don’t forget, these events are free but we do ask that you register before attending to avoid disappointment as spaces are limited. You can also check out our website for more upcoming meetups and user groups, or follow us on Twitter for updates. We look forward to seeing you all again in 2014!

Monday:

The week begins with the London Ruby Users Group who come to Skills Matter for their first meet-up of 2014. At this months meetup Javier Ramirez talks about dealing with big data in PI Analytics with Redis and Bigquery. Javier will be followed by Julien Letessier, wo will be speaking about using data tiering to squeeze scale out of SQL.

Register for your place now!

Tuesday:

The London Java Community will be discussing Android and The Web of Things on Tuesday. Asking questions like ‘what if every day objects could all become part of a gigantic network also known as the Internet of Things?’ And ‘what if your watch, guitar, bike or bottle of organic iced-tea could all have an active digital identity on the Web? By combining technologies such as NFC, QR-codes, Bluetooth low energy and Android smart phones, this becomes an ideal framework to implement the Web of Things…

For more information and to register your place, click here.

Also on Tuesday, the London Ajax Meetup will be joined by Jamie McCrindle & Santi Albowe for a walkthrough of how they’re putting thei AngularJS apps together using TypeScript, Yeoman, Restangular, a RESTful API, S3 and a CDN.

Register your place now!

Wednesday:

Julia programming language logoOn Wednesday we’re very excited to welcome the first meeting of the London Julia Users Group. As a relatively new programming language of interest in the emerging field of Data Science, Julia has many features to commend it over existing approaches, not the its speed of execution.

The discussion will look at using Julia on all platforms: Linux, OSX and Windows; getting up and running, the Julia package system and JuliaStudio IDE, plus any teething problems, trials and tribulations.

Register you place for this meetup now!

Thursday:

Finally, on Thursday, we welcome the F#unctional Londoners for their first meet-up of 2014. At this months session Ross McKinlay will present ‘SQL Type Provider Deep Dive’. Ross has over 20 years programming experience in a wide variety of different languages and technologies, ranging from games and financial markets to fraud prevention and investigation. He has more recently been working on F# type providers. He loves squirrels, physics, electronics, robotics, functional programming, programming languages in general and squirrels.

Book your place for the F#unctional Londonders meetup now!


What did you get up to in 2013? And what are you looking forward to in the world of Open Source in 2014? Let us know in the comments below!

This Week at Skills Matter: 9th-13th of November

Here’s what’s coming up st Skills Matter this week!

Monday:

The Ruby User Group will be in Monday for their December meet-up with a trio of talks from Tymon Tobolski on ‘The Solution To Assets Management In Rails’, Rosario Rascun talks about ‘A Fizzbuzz To Rule Them All’ and finally Najaf Ali gives a talk on ‘From A Raw TCP Socket To A Rails Apllication’. It’s a fantastic line-up and LRUG always proves to be a popular event so make sure you register on our website!

IMG_3699

Tuesday: 

On Tuesday we will will be graced with the arrival of Kelly Waters for an In The Brain session around Kelly’s Agile Journey. Anyone interested in Agile will find this talk enjoyable and useful. However it is particularly useful for managers at all levels – executives, senior managers, programme & project managers, team leaders, development managers, product managers, etc.

Thursday and Friday:

Our final conference of 2013 – The Groovy & Grails eXchange will be taking place with some fantastic speakers such as Guillaume LaForge (the Groovy project manager), Graeme Rocher (the project lead and co-founder the of Grails web application framework) and many more. There is still time to grab a ticket and learn from their vast knowledge and experience, as well as discovering their roadmap for the future – including Groovy 3.0, what it is, how to use it and how it’ll make an impact on your work. We plan to end the year of conferences with a bang so be sure not to miss, it will be a fantastic 2 days!

This Week at Skills Matter: 11th November – 15th November

Here’s what’s coming up at Skills Matter this week!

Monday:

The London Ruby User Group November meet-up wilandrewnesbittl have two talks, the first from Andrew Nesbitt on ‘Controlling Robots with Ruby’ where he will look at one particular Ruby library – Artoo. The second is by Tom Cartwright on ‘How to Parse ’Go’.

We also have The London Big-O November meet-up. Two talks will take place in this session, one by John Graham-Cumming on ‘Rolling Hashes and Compression Algorithms’, John will talk about some of the uses of rolling hashes for string comparison and compression focussing on the rsync protocol, a spam filter, and a delta compression technique. The second will be from Jose Llarena on ‘Mixture of Markoc Chains’. Jose will describe the representation of Mixture of Markov Chains as a graphical model and much more.

Tuesday:

The London Ajax User Group will be in Tuesday for their November meet-up. Why not come and catch up on all the latest LAUG news?

Vaughn Vernon will be talking at our first In The Brain session of the week, this talk ‘Reactive DDD with Scala and Akka’ is not to be missed. Vaughn will be exploring the vaughn_vernonuse of the Actor Model with DDD. He will explain how the basic ideas of the Actor Model and DDD can greatly simplify our ability to comprehend and use concurrency and distribution.

The second In The Brain session will be held by Jon Jagger with a talk on ‘Rethinking Kanban’. Another fabulous talk not to be missed, Jon is a renowned software coach/consultant/mentor/trainer/programmer and all round Agile expert. There is much to learn from him!

Wednesday:

Wednesday welcomes the London Scala User Group. They will be treated to a talk from Patrick Wendell who will introduce Apache Spark – ‘Spark, Scala, and the Berkeley Data Analytics Stack.’



Stay up to date with the latest from Skills Matter! Follow us on Facebook, Twitter, Google+, or sign up to our newsletter.