Comments (36)
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.
Thanks, let me look at it
Original comment by [email protected]
on 14 Oct 2008 at 1:10
from mockito.
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.
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.
>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.
Original comment by [email protected]
on 21 Oct 2008 at 2:40
- Added labels: Priority-Low
- Removed labels: Priority-Medium
from mockito.
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.
Original comment by [email protected]
on 2 May 2009 at 8:31
- Changed title: make spy working with Anonymous classes
from mockito.
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.
Original comment by [email protected]
on 22 Sep 2009 at 9:02
- Added labels: Type-Enhancement
- Removed labels: Type-Defect
from mockito.
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.
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.
[deleted comment]
from mockito.
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.
>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.
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.
No worries, take your time.
Original comment by [email protected]
on 11 Nov 2009 at 1:10
from mockito.
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.
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.
Original comment by [email protected]
on 11 Nov 2009 at 9:09
- Added labels: Priority-Medium
- Removed labels: Priority-Low
from mockito.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
"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.
Oh right, thanks for info!
Original comment by [email protected]
on 26 Dec 2009 at 11:09
from mockito.
[deleted comment]
from mockito.
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.
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)
- NPE on verification when multiple threads used HOT 4
- New spying feature HOT 9
- allow stubbing with callbacks HOT 4
- Want to extend Mockito class to include my own matchers HOT 3
- Arguments are saved by a reference HOT 4
- PATCH : Performance Enhancement for MockHandler : Search matchers once instead of twice HOT 7
- ArrayEquals throws exception HOT 4
- @Mock annotation does not work very well with Eclipse and IDEA HOT 3
- when arguments are different the exception now allows using the comparison window HOT 2
- add junit runners that automaticaly initialize mocks annotated with @Mock HOT 2
- interaction gets remembered between tests HOT 13
- Can't stub spied object HOT 5
- Javadocs don't tell all the truth about Mockito spies HOT 3
- InOrder.verify() displays the actual invocation on error when arguments are different HOT 19
- verify throws an IllegalArgumentException for overloaded method where array argument is incorrect HOT 4
- Checking the method calls ordering in multi-thread environment. HOT 7
- Varargs stubbing produces incorrect behavior HOT 3
- Verify without method call causes errors in other tests. HOT 8
- Upload mockito to the Central Repository
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from mockito.