Export to GitHub

mockito - issue #481

Cannot mock/spy Lamda functions


Posted on Mar 29, 2014 by Swift Kangaroo

What steps will reproduce the problem? 1. spy(someFunctionalInterfaceImplementedByALamdaFunction) 2. spy(lamdaFunction)

Example: createCredentialsFunction = r -> expResult; createCredentialsFunction = spy(createCredentialsFunction);

What is the expected output? What do you see instead? expect a spy on the Lamda function or interface

results in Mockito cannot mock/spy following: - final classes - anonymous classes - primitive types

What version of the product are you using? On what operating system? JDK 8

Please provide any additional information below.

Comment #1

Posted on Mar 31, 2014 by Happy Panda

Could you provide some code?

Comment #2

Posted on Mar 31, 2014 by Swift Kangaroo

See my example above ;-)

but for more context, imagine a Supplier FuncitonalInterface,

String expResult = "Some String"; Supplier supplier = r -> expResult; //A lambda funciton returning the value. supplier = spy(supplier);

This code won't work. My guess is that since lambdas are anonymous functions, that Mockito cannot currently spy on them.

Let me know if you need more. Thanks!

Comment #3

Posted on Apr 1, 2014 by Happy Panda

I must admit that it is interesting case but to be honest I do not see application of this case in real world situation. I mean: There is no use of spying Lambda Functions. Maybe I am wrong so please provide some example where such application of mockito is sensible.

Comment #4

Posted on Apr 21, 2014 by Happy Horse

I don't think it's possible to mock a lambda :

  1. it makes no sense to mock a lambda or to spy one
  2. it is the JVM that generates the lambda code so ASM/CGLIB cannot do magic there

However :

  1. In the JDK8 a lambda must implement a single method interface, why not mock this interface instead
  2. In the master on github there's a AdditionalAnswers.delegatesTo answer that may help with this use case, if you can try it out...

Anyway if you have ideas to contribute, please do a PR ;) Thanks for trying the latest JDK features with mockito :)

Cheers, Brice

Comment #5

Posted on Apr 21, 2014 by Happy Horse

(No comment was entered for this change.)

Comment #6

Posted on Apr 21, 2014 by Massive Monkey

Mockito definitely needs some work to get it more java8 - ready. We should make use of lambdas in our APIs, too.

Thanks for report!

Comment #7

Posted on Apr 27, 2014 by Swift Kangaroo

Well if it's not possible then that's another story, but the use cases are real:

It does make sense to spy an interface implemented by a Lambda. Just how you are able to spy a List backed by a real instance, so too should you be able to spy a Consumer backed by a Lambda Function.

For example,

Consumer consumer = s -> System.out.println("Received String: " + s); //This breaks Mockito. consumer = spy(consumer);

In this example I inlined the Lambda, but if I obtained that object/function from somewhere else, and I want to spy on it, I shouldn't care whether it's a Lambda or a Class.

Hope that clarifies things a little bit.

Thanks!

Comment #8

Posted on Jun 27, 2014 by Happy Horse

Did you tried delegatesTo as a workaround ?

Comment #9

Posted on Jun 27, 2014 by Swift Kangaroo

Hi, I'm not aware of that workaround. Can you show it to me? Thanks!

Comment #10

Posted on Jun 29, 2014 by Happy Horse

That would be something like :

LamdaSAMType spied_lambda = mock(LamdaSAMType.class, AdditionalAnswers.delegatesTo(the_actual_lamda_reference));

see comment #4

Status: New

Labels:
Type-Enhancement Priority-High JDK8 lambdas