How to Mock a Lambda expression?

6,110 views
Skip to first unread message

Harry Callahan

unread,
Oct 31, 2018, 9:02:14 AM10/31/18
to mockito

Google has not been able to help me with this question so far.

The example below is a ridiculous contrived one just to help frame the question which is about Mockito.


Let's say I have a class with a Lamda defined:-

public class MyFunctions {
   
public Function<String, String> upperCaseFunction = str -> { return str.toUpperCase(); };
}



And lets say I use this function somewhere like so.

public class SomeComponent {

   
private MyFunctions myFunctions;

   
public String reverse(String input) {
     
Stream<String, String> stream = Stream.of(functions.upperCaseFunction);
     
return stream
       
.flatMap(function -> function.apply(input).... etc etc
 
}

}



I now wish to test SomeComponent and mock MyFunctions.

My problem is I can't figure out how to mock the Lambda expression in MyFunctions?

I have tried the following so far and cannot seem to setup the lambda properly.

@RunWith(MockitoJUnitRunner.class)
public class SomeComponentTest {

    private static final String TEST_STRING = "hello";

   
@Mock
   
private MyFunctions myFunctions;

   
@InjectMocks
   
private SomeComponent someComponent;

   
@Before
   
public void setUp() {
     given
(myFunctions.upperCaseFunction).thenReturn(Function<String, String>);  // call to reverse throws MissingMethodInvocationException
     given
(myFunctions.upperCaseFunction.apply(TEST_STRING)).thenReturn("HELLO");  // call to upperCaseFunction.apply throws NullPointer
   
}

   
@Test
   
public void testReverse() {
     
String result = someComponent.reverse(TEST_STRING);  
           
assert(result.equals("HELLO");

   
}
}


Can anyone give me any advise on how to Mock MyFunctions and the lambda expression it contains?



Tim van der Lippe

unread,
Oct 31, 2018, 9:49:32 AM10/31/18
to moc...@googlegroups.com
I don't think we should allow the mocking of a Function directly. However, you can probably create a mock of a test class and reference the method from this mock.

E.g. (Note that I have not run this code, but I hope you get the gist of it and it should "just" work)

```java
public class Test {
  @Mock
  private Mock mock;

  private SomeComponent someComponent;

  @Before
  public void setup() {
    when(mock.callback()).thenReturn("Hello");
    someComponent = new SomeComponent(mock::callback);
  }

  @Test
  public void test() {
    String result = someComponent.reverse("hello");
    assertEquals(result, "Hello");
  }

  static class Mock {
    public String callback() {
      return "callback";
    }
  }
}
```

Op wo 31 okt. 2018 om 13:02 schreef Harry Callahan <harry42...@gmail.com>:
--
You received this message because you are subscribed to the Google Groups "mockito" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mockito+u...@googlegroups.com.
To post to this group, send email to moc...@googlegroups.com.
Visit this group at https://groups.google.com/group/mockito.
To view this discussion on the web visit https://groups.google.com/d/msgid/mockito/3f0ab191-0d04-4cd7-8bc6-24a541d951e1%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Harry Callahan

unread,
Oct 31, 2018, 11:02:13 AM10/31/18
to mockito
Thanks for your time and help Tim. 

Before I got to read your suggestion I went with the following

@Before
   
public void setUp() { myFunctions.upperCaseFunction = string -> { return "HELLO"; };
}


And then setting locally in each test where I wanted a different value.

@Test
public void testFailure {
     myFunctions.upperCaseFunction = string -> { return "xxx";};
// some assertions
}


I will consider your approach though and may refactor.

I'm using an old version of Mockito so thought that might have been an issue. I'm surprised that recent versions don't allow you to Mock a function since they should be considered 1st class objects just like any other interface right?

Tim van der Lippe

unread,
Oct 31, 2018, 11:03:28 AM10/31/18
to moc...@googlegroups.com
I am not sure if we specifically disallow it. We would need to look into it. Feel free to submit a bug report on our GitHub issue list with a reproduction case with the latest version of Mockito.

Op wo 31 okt. 2018 om 15:02 schreef Harry Callahan <harry42...@gmail.com>:

Harry Callahan

unread,
Nov 1, 2018, 4:07:49 AM11/1/18
to mockito
Ok, I will have a play with the latest version and may raise an issue. cheers.
Reply all
Reply to author
Forward
0 new messages