mlinhard / mockito

Automatically exported from code.google.com/p/mockito
0 stars 0 forks source link

Cannot mock/spy Lamda functions #481

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
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.

Original issue reported on code.google.com by JWelling...@gmail.com on 29 Mar 2014 at 5:34

GoogleCodeExporter commented 9 years ago
Could you provide some code?

Original comment by albers...@gmail.com on 31 Mar 2014 at 8:49

GoogleCodeExporter commented 9 years ago
See my example above ;-)

but for more context, imagine a Supplier<String> FuncitonalInterface,

String expResult = "Some String";
Supplier<String> 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!

Original comment by JWelling...@gmail.com on 31 Mar 2014 at 8:57

GoogleCodeExporter commented 9 years ago
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.

Original comment by albers...@gmail.com on 1 Apr 2014 at 10:31

GoogleCodeExporter commented 9 years ago
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

Original comment by brice.du...@gmail.com on 21 Apr 2014 at 6:40

GoogleCodeExporter commented 9 years ago

Original comment by brice.du...@gmail.com on 21 Apr 2014 at 6:41

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

Thanks for report!

Original comment by szcze...@gmail.com on 21 Apr 2014 at 7:09

GoogleCodeExporter commented 9 years ago
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<String> backed by a real instance, so too 
should you be able to spy a Consumer<String> backed by a Lambda Function.

For example,

Consumer<String> 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!

Original comment by JWelling...@gmail.com on 27 Apr 2014 at 4:34

GoogleCodeExporter commented 9 years ago
Did you tried `delegatesTo` as a workaround ?

Original comment by brice.du...@gmail.com on 27 Jun 2014 at 4:53

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

Original comment by JWelling...@gmail.com on 27 Jun 2014 at 4:55

GoogleCodeExporter commented 9 years ago
That would be something like : 

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

see comment #4

Original comment by brice.du...@gmail.com on 29 Jun 2014 at 3:50