EDIT: With Mockito 2 you no longer need to use the following method. Lambdas are supported out of the box. You can use argThat(str -> str.length >5).
Java 8 is pretty cool. We (finally!) got Lambda Expressions in Java and a lot of other goodies. At Coveo, we started working with Java 8 as soon as the first stable release was available. As mentioned in my previous blog post, one way we’re using Java 8 is in our unit tests.
Let’s say we want to test that adding an Employee to a Company correctly invokes the CompanyDal class with the right information.
When testing the Company class we’ll want to mock our CompanyDal interface. We use the great Mockito library for our mocking needs.
This is a good test as it validates that the Company class interacts with the CompanyDal class as expected.
Now.. how can we do this verification?
We could be tempted to do
But that won’t work since the two Employee instances are not the same. This is caused by the deep copy in the Company class.
Note: For the sake of this example, we need to pretend that we can’t override Employee’s equals() method to use value equality instead of reference equality.
What we need to do is verify that the Employee passed to the CompanyDal has the same name property as the one passed to the Company class.
This can be done using Mockito Matchers.
This will produce the following message in case of test failure
Argument(s) are different! Wanted:
Employees must have the same name
-> at com.coveo.CompanyTest.canFindEmployee(CompanyTest.java:71)
Actual invocation has different arguments:
-> at com.coveo.Company.addEmployee(CompanyTest.java:46)
This is good! But this test suddenly went from 4 lines of code to 15 lines!
The matches() method could easily be replaced by a java.util.Predicate!
But we’ll need an adapter class to bridge Mockito’s Matcher with Predicate. Introducing LambdaMatcher!
LambdaMatcher is really easy to use. Here’s our rewritten addingAnEmployeeRegistersItInTheDal test.
And if you want a description
This new code will generate the same nice error message as above.. but it is much simpler! If you want to save even more time, you can create the following static method.
Which will result in the following test.
That’s it! Feel free to use the LambdaMatcher class in your own projects and add some Lambda to your unit tests!