2×4. If you expect to pass a lambda expression into your code, then it's usually the right
thing to have your test also pass in a lambda expression.
Most test doubles end up being the result of more complex expectation setting. In these situ-
ations, frameworks such as Mockito are often used to easily generate test doubles. Let's con-
sider a simple example in which we want to produce a test double for a List . Instead of re-
turning the size of the List , we want to return the size of another List . When mocking the
size method of the List , we don't want to specify just a single answer. We want our answer
Example 7-15. Using a lambda expression in conjunction with the Mockito library
List < String > list = mock ( List . class );
when ( list . size ()). thenAnswer ( inv -> otherList . size ());
assertEquals ( 3 , list . size ());
Mockito uses an Answer interface that lets you provide alternative implementation behavior.
In other words, it already supports our familiar friend: passing code as data. We can use a
lambda expression here because Answer is, conveniently, a functional interface.
Lazy Evaluation Versus Debugging
Using a debugger typically involves stepping through statements of your program or attach-
ing breakpoints. Sometimes you might encounter situations using the streams library where
debugging becomes a little bit more complex, because the iteration is controlled by the lib-
rary and many stream operations are lazily evaluated.
In the traditional imperative view of the world, in which code is a sequence of actions that
achieve a goal, introspecting state after or before an action makes perfect sense. In Java 8,
you still have access to all your existing IDE debugging tools, but sometimes you need to
tweak your approach a little in order to achieve good results.
Logging and Printing
Let's say you're performing a series of operations on a collection and you're trying to debug
the code; you want to see what the result of an individual operation is. One thing you could