Java & JEE

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.


First class functions in Java 8

Raoul-Gabriel Urma

This is a guest post from Raoul-Gabriel Urma, a PhD candidate in Computer Science at the University of Cambridge. His research centers on programming languages and software engineering. Raoul has written over 10 peer-reviewed articles and given over 20 technical talks at international conferences. He has worked for large companies such as Google, eBay, Oracle, and Goldman Sachs, as well as for several startup projects – and has recently written a book on Java 8 in Action: Lambdas, Streams and functional-style programming by Manning.

Raoul also teaches a course on modern development with Java 8 at Skills Matter, alongside Jim Gough & Richard Warburton. 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!


Java 8 adds functions as a new form of value. What does this mean? Let’s look at a simple example.

Suppose you want to filter all the hidden files in a directory. You need to start writing a method that given a File will tell you whether it is hidden or not. Thankfully there’s such a method inside the File class called isHidden. It can be viewed as a function that takes a File and returns a boolean.

However, to use it you need to wrap it into a FileFilter object that you then pass to the File.listFiles method as follows:

File[] hiddenFiles = new File(".").listFiles(new FileFilter() {
   public boolean accept(File file) {
      return file.isHidden();
   }
});

Ouch, that’s pretty obscure! We already have a function isHidden that we could use, why do we have to wrap it up in a verbose FileFilter object?

In Java 8 you can rewrite that code as follows:

File[] hiddenFiles = new File(".").listFiles(File:: isHidden);

Wow! Isn’t that cool? We already have the function isHidden available so we just “pass” it to the listFiles method. Our code now reads closer to the problem statement.

The use of File::isHidden is a rather special case of a new feature called method references in Java 8. Given that methods contain code (the executable body of a method), then using methods as values is like passing code around.

I hope this brief post has sparked some interest in Java 8! You can find a longer explanation in this 10min animated video we put together:

 


 

Friday Round Up: 4th November – 8th November

It’s been a quiet week in the line of conferences but we’ve had a very busy week here at Skills Matter hosting nine free events with our community. These included three In The Brain sessions and six User Group meet-ups all receiving positive feedback and marvellous turnouts! These events wouldn’t be what they are without our community so we’d like to take this opportunity to thank all the attending delegates and speakers for learning and sharing at Skills Matter this week.

This week in SkillsCasts:

IMG_3261

Monday saw the arrival of the London Java Community with a talk from Martijn Verburg and Richard Warburton ‘The Bleeding Edge’ where they spoke about what happens to your technology stack if you’re willing to take a risk. Martijn and Richard work together at jClarity and are running production systems using Html 5, Angular.js, vertx, Mongo, groovy and are deploying using chef. They explained how it has been an interesting ride: how some things worked really well and how some things didn’t. They also explained how they ended up with such a diverse stack and how to make technology choices in a fairer way.

Infracoders London were also in for their November meet-up with an interesting talk on ‘A Journey of Windows Infrastructure Automation At thetrainline.com’ – a brief history, where it started, what’s happening now and where it’s heading using Chef, VMWare, power-shell plus a few other tools.

The London Clojurians had three separate lightening talks from the speakers, Henry Garner, Kris Jenkins and Jamie Brandon. This is definitely one to catch up on!

Oren Eini (aka Ayende Rahien) graced us with a first-rate In The Brain session, with a talk on ‘The DB Disassembly Kit’. Oren went into the details that make up the different components in a database, how they are put together and what the different design choices you have for each component, and how they work together.

Our second In The Brain session of the week was from Susanne Madsen who spoke about ‘Project Leadership: Are we too busy with the urgent to focus on the important?’ A very interesting and relevant talk – worth a watch if you missed out!

The London Pyramid Group had two awesome talks, the first from Jon Staley who gave a quick intro to Deform & Colander and spoke about how you can wrangle them into doing what you want. The second from Riley Doyle who covered key lessons learned in building an advanced ‘DNA Search Engine’ with Pyramid.

The London Lua had a talk on ‘Lua & Corona SDK – Cross platform mobile game development’ for their November meet-up. This talk is great for anyone interested in a basic beginners guide to getting started with indie game development in Corona and Lua…

The final In The Brain session was with Ian Plosker who spoke about The Triumph of Simplicity: how database complexity will be replaced by simple services. He discussed why the level of complexity in storing and querying data has exploded and how database software eventually will be overrun by simple services. The Skillscast to this talk will be available in two weeks.

Next week at Skills Matter:
Monday – The London Big-O November meet-upLondon Ruby User Group November meet-upLondon AJAX User Group November meet-up

Tuesday – In The Brain of Vaughn VernonIn The Brain of Jon Jagger

Wednesday – London Scala User Group November meet-up


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

QCon – Getting to know Ian Robinson

Image

SkillsMatter got a few minutes alone with Ian Robinson the Director of Customer Success for Neo Technology at QCon 2013. He agreed to let Russ Miles pick his brain. Here’s how it went down.

(RM) So we’re here with Ian Robinson of Neo Technology. In those two years I imagine a lot has changed at Neo. Loads of things have come and gone in the database itself. What have been memorable moments in those just over two years that have really popped out and you’ve thought – we’ve got that absolutely right, working on that (!)

(IR) Well, I have seen a lot over the past couple of years. A lot of customer growth, and a lot more functionally with the database. So when I first started with Neo I spending a lot of time working with customers, helping design, develop, and deploy solutions – and I’ve seen a number of things there. Neo4j is now back in Adobe’s Creative Cloud, it’s the social element of Adobe’s captivity cloud, so we’ve been working a lot with Adobe around that – It’s also running the largest parcel delivery network in Europe, again working with the guys who develop in that – very interesting and fruitful times.

More recently, in regard to the product itself, it’s seen enhancements to the data model. We’re introducing labelling which is actually a very powerful capability – very simple but very powerful. That’s coming this Summer.

Even more recently I’ve joined the engineering team here in London working on creating a distributed graph database. 

Wow ok – I imagine that’s a highly requested feature – the ability to distribute a massive graph potentially in different locations, for different needs. You mentioned the labeling  How does it differ from setting properties – what does labeling give the user that you couldn’t get before?

What you have today is nodes, relationships, and properties. Every relationship has a name, effectively has a label, but the nodes themselves are completely untyped. So very often people ask ‘How can we tell that this Node represents a customer or a product?’ The strategies today are very adhoc. Some people have a add a property called type, or label. Other people link relationships to a type name. What we’re promising with labels is the ability to support this at the level of the data model itself. So with labelling, you’re be able to attach one or more labels to a node and you’re going to say effectively this node is a user or a customer – very similar to using labelling in Gmail for instance.

You can have multiple labels – for instance User and Customer – or User and Adminstrator and so on. Then once we’ve got those labels we can start associating constraints with them, we can use them for reasoning about the graph within the database itself – so we can make more informed choices when we’re optimising queries. It gives us a lot of power, but it also gives the developer a lot of power.

What are the key features that are coming up that developers should be most excited about. And what’s on Neo Technology’s horizon?

So the ‘big ticket’ things are the enhanced data-model – so that includes labelling, includes enhanced indexing, and I think we’ll also see the query language effectively being able to treat the graph database, not only as a graph, but also a document storer. 

On top of the that, going out towards the end of the year, beginning of next year, looking at distributed graph, being able to scale horizontally for writes and enormous volumes of data. Even in the interim we’re lifting the limits on the amounts of data you can store in a single instance. So today it’s in the 10s of billions – by the middle of this year there will be no upper limit on how much data can be stored in a single instance. 

Like what he has to say? Check out Ian’s profile here and have a gander at his other talk’s and his Neo4j Tutorial course

ALSO the Neo4j user group existing and upcoming talks.

Summer of Architecture 2012 @skillsmatter

The sun is out and here at Skills Matter HQ we’re watching out eagerly for the ice cream man — but even more exciting than an ice cream with a flake in it is the big names in Domain Driven Design, CQRS and Software Architecture that we have coming to join us over the coming weeks and months.

We’ve lined up a steady flow of architecture rock stars for the summer, including headliners Udi Dahan, Greg Young and Eric Evans, supported by experts Simon Brown, Andreas Ohlund and Alberto Brandolini to provide an exciting range of talks, discussions and practical workshops on all things architecture.

The only thing we’re missing is you — we’d love to see you soon!

https://i0.wp.com/skillsmatter.com/do/summer-of-architecture-2012/summer-of-architecture-2012-combined-header.gif