Code Monkey home page Code Monkey logo

Comments (36)

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
Turns out this happened because the instance I wanted to spy on was created 
with an 
anonymous class. More info here: 
http://java.sun.com/javase/6/docs/api/java/lang/
Class.html#getSimpleName()

Original comment by [email protected] on 14 Oct 2008 at 12:44

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
Thanks, let me look at it

Original comment by [email protected] on 14 Oct 2008 at 1:10

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
Unfortunately you won't be able to create a spy of an anonymous class because 
this
class is implicitly final. I fixed it so now there is nicer exception saying why
can't you do it. Fix is in trunk.

I will look further, maybe there is a clean way of getting anonymous classes 
working
with spy()

Original comment by [email protected] on 14 Oct 2008 at 1:38

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
You can't generate a wrapper class? The anonymous class do have a base or 
interface 
whos contract they adhere to. Though I don't know how you would handle it if 
they 
define their own public methods. Maybe that part can be ignored/thrown at, 
since it 
is probably an unlikely event anyway.

Original comment by [email protected] on 14 Oct 2008 at 3:23

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
>The anonymous class do have a base or interface whos contract they adhere to.

Yes, I'll try fix it in next version

Original comment by [email protected] on 21 Oct 2008 at 2:38

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024

Original comment by [email protected] on 21 Oct 2008 at 2:40

  • Added labels: Priority-Low
  • Removed labels: Priority-Medium

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
Will try to fix it after 1.7. I don't seem it's that important because spying on
anonymous classes is not very usual and one can always convert anonymous class 
into
nested.

Original comment by [email protected] on 11 Jan 2009 at 10:48

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024

Original comment by [email protected] on 2 May 2009 at 8:31

  • Changed title: make spy working with Anonymous classes

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
I officially don't have time for this feature :) 

If anyone is keen on this feature, please submit a patch.

Original comment by [email protected] on 22 Sep 2009 at 9:02

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024

Original comment by [email protected] on 22 Sep 2009 at 9:02

  • Added labels: Type-Enhancement
  • Removed labels: Type-Defect

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
I've long since worked around it, and have not run into the need to spy on, 
well, 
anything really, since. So it's no longer important to me.

Original comment by [email protected] on 22 Sep 2009 at 10:45

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
One simple workaround would be for Mockito implement the following method:
static <T> T spy(Class<? super T> clazz, T object) 

This would let you specify the interface seperately, so mockito won't have to 
build a
proxy of the actual object, but of the interface instead. The proxy could 
however
still redirect incoming calls to the supplied object.

This should solve the problem with final and anonymous classes.

Does this make sense to anyone?
Would it be hard to implement?

Original comment by [email protected] on 11 Nov 2009 at 11:35

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
[deleted comment]

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
Ok, I withdraw my patch, it doesn't work for proxys.
It is easy to fix that, but then some tests break.

It's easy to fix the tests but the question boils down to:
Why does Mockito require that the spiedInstance is of the exactly same type as 
the
declared class? Is there any fundamental limitation that requires this, or can 
that
requirement be removed?

If so, I have a working patch available now.

Original comment by [email protected] on 11 Nov 2009 at 12:39

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
>Why does Mockito require that the spiedInstance is of the exactly same type as 
the
>declared class?

I guess it was the easiest :)

Given that we allow different mocked type and spied instance what type should be
actually proxied? spiedInstance.getClass() or mockedType?

Original comment by [email protected] on 11 Nov 2009 at 12:49

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
I think mockedType should be proxied. That should work since 
spiedInstance.getClass()
is guaranteed to support all methods from mocketType.

I will send a new patch as soon as I have working tests for final classes, 
anonymous
classes and proxy classes.

I currently need to disable or weaken a couple of conditions in the code, which 
makes
me nervous, but I hope I won't break too much. :-)

Original comment by [email protected] on 11 Nov 2009 at 12:58

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
No worries, take your time.

Original comment by [email protected] on 11 Nov 2009 at 1:10

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
I've tried digging into the code now, but it seems I am in way over my head, so 
I am
giving up :-(
However, I still think the original strategy is a sane one.

My suggested API change is:
public static <T, U extends T> T spy(U object, Class<T> clazz);

Hope someone with more understanding of the Mockito core can implement this 
some day.


Original comment by [email protected] on 11 Nov 2009 at 2:25

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
I made a proof of concept patch and emailed it to the mailing list, but I might 
as
well put it here as well:

Original comment by [email protected] on 11 Nov 2009 at 4:15

Attachments:

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024

Original comment by [email protected] on 11 Nov 2009 at 9:09

  • Added labels: Priority-Medium
  • Removed labels: Priority-Low

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
Hi man,

Currently, we try not to introduce new methods to the main Mockito class. Have 
a look
at withSettings(). 

AFAIU the goal of this enhancement is to be able to spy on anonymous classes. 
I'm not
sure why we need to introduce new methods. Can we make it working first with the
original spy() method, e.g. to support:

Foo foo = spy(new Foo() {});

Makes sense?

Original comment by [email protected] on 11 Nov 2009 at 9:30

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
Ok, I can understand not wanting to introduce entirely new features or rewriting
large parts of the code.

Adding a new method should be fully backwards compatible though.

The reason for adding a new method is, in my opinion, that the original 
approach is
wrong.
Spying should not require you to extend a final, anonymous or proxied class, 
which
this basically requires you to do, By supplying the base class or interface 
you're
actually interested in, you avoid that whole mess, without any loss at all for 
most
spying use cases.

For a real time use case, I have a service interface, that performs certain
operations, possibly against a database in the background.
In order to make such implementations transactional, I have made a
TransactionProxy-class, which has a method for wrapping an object in a proxy and
providing the proper transaction-logic:

ServiceImpl si = new ServiceImpl();
Service s = TransactionProxy.wrap(Service.class, si);

It is very hard to spy on such an object in Mockito without introducing this 
new method.

Our current workaround is unfortunately to create the mock manually which is a 
bit
sad, since we're already using a perfectly good mocking framework.

Original comment by [email protected] on 12 Nov 2009 at 7:04

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
Hey,

I'm open to new features and I can help but I need to understand the purpose :)
Starting from the example you showed what is the use case?

ServiceImpl si = new ServiceImpl();
Service s = TransactionProxy.wrap(Service.class, si);
...

Original comment by [email protected] on 12 Nov 2009 at 7:42

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
Basically the use case is that we run with real code, but want to verify that 
some
other code calls it the correct amount of time.

ServiceImpl si = new ServiceImpl();
Service s = TransactionProxy.wrap(Service.class, si);
OtherService s2 = new RealOtherService(s);
s2.doSomeOperation();
verify(s, times(2)).update();

That's pretty much exactly our use case that prompted this patch, but with some
changed names and removal of irrelevant code.

Original comment by [email protected] on 12 Nov 2009 at 8:04

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
ok, cool.

So the use case you show is something Mockito already does. What's so special 
about
the ServiceImpl that requires extra changes?

Original comment by [email protected] on 12 Nov 2009 at 6:01

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
Sorry, i forgot the actual spy call, here's how it should look:

ServiceImpl si = new ServiceImpl();
Service s = TransactionProxy.wrap(Service.class, si);
Service mySpy = Mockito.spy(s);

OtherService s2 = new RealOtherService(mySpy);
s2.doSomeOperation();
verify(mySpy, times(2)).update();

This is currently not possible in Mockito since spy won't work on a proxied 
object.

Original comment by [email protected] on 12 Nov 2009 at 6:06

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
Ok I understand now. So the problem is that spy won't work on a proxied object. 
The
spy you're asking for is the behavior of Mockito spies < 1.8.0. Actually, there 
were
many users asking for 'true' partial mocks (meaning to just mere delegators). 
Anyway,
I think the behavior you want can be implemented using current api (correct me 
if I'm
wrong):

        //given
        final IMethods delegate = mock(IMethods.class);
        when(delegate.simpleMethod()).thenReturn("simple");
        when(delegate.otherMethod()).thenReturn("other");

        IMethods mock = mock(IMethods.class, new Answer() {
            public Object answer(InvocationOnMock invocation) throws Throwable {
                return invocation.getMethod().invoke(delegate,
invocation.getArguments());
            }
        });

        when(mock.otherMethod()).thenReturn("overridden other");

        //then
        assertEquals("simple", mock.simpleMethod());
        assertEquals("overridden other", mock.otherMethod());

Original comment by [email protected] on 12 Nov 2009 at 6:34

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
Yes, that looks like it would work, though with slightly more effort than with 
my 
proposal.

It's an acceptable solution though!

Thanks!

Original comment by [email protected] on 12 Nov 2009 at 7:33

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
That's true, you have to code some more ;) However you can refactor a bit and 
get:

IMethods mock = mock(IMethods.class, byDefaultDelegateTo(delegate));

Original comment by [email protected] on 12 Nov 2009 at 9:05

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
Mocking/spying anonymous classes would be extremely useful for Scala, since 
closures in Scala seem to be 
represented by anonymous classes.

Original comment by [email protected] on 5 Dec 2009 at 8:07

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
FYI, Spying on anonymous classes was implemented in Mockito 1.8.1

Mocking (Mockito.mock(...)) anonymous classes does not make sense :)

Original comment by [email protected] on 7 Dec 2009 at 2:25

  • Changed state: Fixed
  • Added labels: Milestone-Release1.8.1

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
"Mocking (Mockito.mock(...)) anonymous classes does not make sense :)"

Quite true. A silly mistake on my part!

With regards to spying on closures in Scala, it appears they're actually final 
classes- and not 
anonymous classes as I had earlier supposed.

For the curious: PowerMock can't quite get around this yet because closures are 
considered inner 
classes, and there seem to be issues with final inner classes.

Original comment by [email protected] on 24 Dec 2009 at 10:34

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
Oh right, thanks for info!

Original comment by [email protected] on 26 Dec 2009 at 11:09

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
[deleted comment]

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
I got into the same issue now when trying to use Mockito with Spring. The issue 
is that Spring creates a proxy/anonymous class in order to apply it's aspects 
(JPA persistence related - wrapping for transactions etc), thus when I get to 
spy on it, it's already an anonymous.
I'll find a workaround, but thought I'd highlight one case when such a feature 
would be useful and which is pretty frequent.

Cheers, Stef.

Original comment by [email protected] on 28 Feb 2013 at 11:16

from mockito.

GoogleCodeExporter avatar GoogleCodeExporter commented on August 27, 2024
Hi stefan,

I don't know precisely how your code is configured, but JDK or CGLIB proxies 
are not mockable or spyable, (Mockito will try to create a subclass in bot 
cases). Even spring cannot proxy another proxy directly, instead they need the 
interface.

In the mockito the API of version 1.9.5 we introduced the following ability for 
some corner cases where mocking or spying is difficult if not impossible :

Mockito.mock(SomeMockableType.class, 
AdditionalAnswers.delegatesTo(someInstanceThatIsNotMockableOrSpyable));

HTH
Brice

Original comment by [email protected] on 13 Mar 2013 at 11:17

from mockito.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.