Eedanna / mockito

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

Mocking does not preserve the annotation on a type #255

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
Hi,

Steps to recreate the problem:
---------------------------------------------------------
1. Create a custom annotation say:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Leaf {}

2. Create a type and annotate it with Leaf
@Lead
public class Leafy {}

3. Create another class Node which has Leafy injected via setter or constructor

4. Write a unit test for class Node and mock Leafy. Check for annotations on 
this mock Leafy object. It will not have annotations on it.

Problem:
---------------------------------------------------------
So if i have a check to see if a constructor argument be of type annotated with 
@Leaf then that check will fail on the mock and will fail the test as well when 
it should not fail. 

I am using 1.8.5 version.

Regards,
Madhav

Original issue reported on code.google.com by unmarsh...@gmail.com on 6 Apr 2011 at 7:37

GoogleCodeExporter commented 8 years ago
Hi Madhav,

Actually this is more a limitation than a bug. The mock engine, which is backed 
by CGLIB, cannot inject annotations on mocks.

I know about one hack for annotations on classes, but for methods or other 
elements of a class, it will require support from the bytecode genration 
backend.

Javassist might help there but it's not a straightforward backend migration.

Regards,
Brice

Original comment by brice.du...@gmail.com on 6 Apr 2011 at 8:11

GoogleCodeExporter commented 8 years ago
Hi Brice,

I might have mistakenly categorized this as a bug. I understand that using
CGLIB this might not be possible at present. However, for my use case i have
managed to spy the actual class instance and then i was able to get the
annotation on the type.

It will be useful to have this as a feature. Let me know if i can contribute
this enhancement if it is required by any one other than me.

Original comment by unmarsh...@gmail.com on 7 Apr 2011 at 5:49

GoogleCodeExporter commented 8 years ago
I am ok supporting it if someone provides a patch (pull request) ;)

Original comment by szcze...@gmail.com on 7 Apr 2011 at 7:52

GoogleCodeExporter commented 8 years ago
I also ran into this issue and wouldn't mind a fix.
I've cloned the repo and am trying to see if I can create a patch. But if 
someone beats me to it I'm okay with that.

Original comment by jaie.wil...@gmail.com on 14 Apr 2011 at 8:05

GoogleCodeExporter commented 8 years ago
ok, cool, go for it

Original comment by szcze...@gmail.com on 14 Apr 2011 at 7:33

GoogleCodeExporter commented 8 years ago
Issue 276 has been merged into this issue.

Original comment by brice.du...@gmail.com on 7 Oct 2011 at 8:31

GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
One potential workaround for this is checking for the annotation on the type 
hierarchy, because the annotation still exists, just on the parent object.

When I encountered this issue, I used Spring's AnnotationUtils to get around it.

I suppose that workaround wouldn't work for people who only want to process 
classes that have the annotation directly on them (and be strict so as to not 
allow inheritance), but if you feel okay just checking for one in the hierarchy 
it works correctly.

I personally feel like it provides more functionality to check up the class 
hierarchy anyway.  So, I was okay with the compromise.

Original comment by mrdanpsmith@gmail.com on 6 Aug 2012 at 8:40

GoogleCodeExporter commented 8 years ago
I just ran into a similar issue spying on a class that had @Subscribe methods 
for the Otto event bus. We are injecting the spy(object) using Dagger into our 
test. Before calling spy() on the object I use reflection to verify that I have 
annotations, but after it injects the spy there is no more annotations on the 
class.

Has anyone come across this issue? Is it something specific to Otto or Dagger? 
Below is some code:

In the header:
@Inject MyObject mObject;

In my test module to inject:
@Provides 
@Singleton 
MyObject providesMyObject() 
      // I verified that annotations @Subscribe are present here
      MyObject object = new MyObject();
      return Mockito.spy(object);
}

Then in the test:
mEventBus.post(new MyEvent());
// myEventListener has @Subscribe, but if I use reflection, it no longer has 
the annotation
Mockito.verify(mObject).myEventListener();

Original comment by ralph.p...@gmail.com on 26 Feb 2014 at 3:32

GoogleCodeExporter commented 8 years ago
I just ran into this. Perhaps, it would be good to mention this somewhere in 
the documentation? In the end it is not a big deal, but would be nice to get 
some hints about it before a debugging session :-)

Original comment by krikava on 15 Apr 2014 at 4:34

GoogleCodeExporter commented 8 years ago
Yes it is a know problem with CGLIB.

Do you want to contribute a known issue wiki page on github :P

Original comment by brice.du...@gmail.com on 21 Apr 2014 at 4:54