• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Mockito: Inner classes on spies/mocks - any way to measure their effect on the real object?

 
Bartender
Posts: 4179
22
IntelliJ IDE Python Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have a class I am unit testing which looks like this:


The real code has some behavior which connects to external services, so I @Spy on the class so I can stub that behavior. But I have a problem now when I am trying to test code in the anonymous inner class (in the example, a Runnable but in real life a callback interface). Here are some example tests I ran:

These are different ways of trying to test the basic idea that aValue gets set. I can test either through the getValue() method, or it would be okay to verify that the setValue() method was called.

[edit] I forgot to mention what the results were. For the first and third tests, the assert fails, the getValue() method returns "None" rather than "Important". The second and fourth tests fail because there are no interactions with the spy when I call the method on the task. In all four tests the "I am called" and "Important set" outputs are recorded so the setValue() method is actually called and with the correct value.[/edit]


I think this comes down to the difference between the 'real' object and the spied object which is a copy. From the API:

Mockito *does not* delegate calls to the passed real instance, instead it actually creates a copy of it. So if you keep the real instance and interact with it, don't expect the spied to be aware of those interaction and their effect on real instance state. The corollary is that when an *unstubbed* method is called *on the spy* but *not on the real instance*, you won't see any effects on the real instance.



So it appears the issues is that there two instances of the object, the spy and the real instance. It looks like the inner class is acting on one part, and all the code I write is acting on the other part. To be honest I don't know which one interacts with the spy and which the real instance, but I can't find a way to get at the other part.

The real class is represents a connection to a remote service. The library I am using is asynchronous and requires a callback. I want to test that, given various results of the callback, my part of the code reacts properly. So it isn't a simple 'set' method (which wouldn't be test worthy but the first pass of the test is this simple). The callback methods themselves will probably just delegate to methods in the outer class, but may have some logic to decide which method to call, I am not sure yet.

Anyone have an idea how I might go about solving this issue? Is there a way in Mockito to explicitly reference the real or spy parts of a spy, or am I barking up the wrong tree and need to re-consider how to implement the callback?
 
reply
    Bookmark Topic Watch Topic
  • New Topic