• 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

how to mock extended procedure?

 
Ranch Hand
Posts: 348
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator




now, in my unit test, how do I mock this.procedure1() not to throw anything?
Thanks
 
Sheriff
Posts: 5555
326
IntelliJ IDE Python Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi David,

This is just like this other question that I answered a while back, and a couple of others before that, which resulted in me writing this blog post on the same topic.

To state the problem you are having: You want to test the method theProcedure() in class Child, but it has a dependency on the method procedure1() in the parent class Parent which is unpredictable and could throw an Exception. You wish to 'mock' procedure1() so that in your test you can guarantee its behaviour to not throw an exception.

A solution is to create a 'Testable' version of the Child class that overrides procedure1() with your desired behaviour, but does not override theProcedure() so that the implementation from class Child is used.

Here's the example of how you would write your test for this example:

Hope that helps.

Tim
 
David Spades
Ranch Hand
Posts: 348
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I see, does this qualify as design problem? since the code is not testable? thanks
 
Tim Cooke
Sheriff
Posts: 5555
326
IntelliJ IDE Python Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Pretty much, yes.

I would tend to use this technique when trying to get legacy code into a test harness. It if were my own code then I'd be considering some refactoring at this point. Interestingly, if you write your tests first before you write your code then it's very unlikely you'd arrive at this solution at all.
 
David Spades
Ranch Hand
Posts: 348
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
yep, you guessed right, it's a legacy code, now falls to me to maintain it. Damn. Oh well, guess that's life as a developer, you "inherit" other's code, pun intended.
 
Sheriff
Posts: 17644
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

David Spades wrote:I see, does this qualify as design problem? since the code is not testable? thanks


I wouldn't want to jump to that conclusion until I had seen the actual code but in all likelihood the design could at least be better. I've used the technique that Tim showed a number of times in the past. One refactoring I've managed to do a few times, when the code is amenable to it, is to extract the procedure to another class and/or introduce an interface. I can then turn to Dependency Injection and inject a stub or mock for testing in place of the actual dependency. That requires the procedure that will be extracted to be fairly decoupled though and sometimes it's not and trying to refactor it unravels the entire fabric of the code.
 
David Spades
Ranch Hand
Posts: 348
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
1. okay, so for extended methods, there's no other way, you just need to provide your own implementation of those methods.
2. Does the same principle also apply to all calls to other methods within the same class?

Thanks
 
Tim Cooke
Sheriff
Posts: 5555
326
IntelliJ IDE Python Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

David Spades wrote:1. okay, so for extended methods, there's no other way, you just need to provide your own implementation of those methods.


As far as I know yes. I don't think the likes of Mockito etc can help you out in this scenario.

David Spades wrote:2. Does the same principle also apply to all calls to other methods within the same class?


Yes. Extend the class for use in your test, and override the method you want to 'mock'.
 
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Have you looked into using JMockit as a means of isolating your code under test. It's free and very robust. You can find out more here: http://jmockit.org/

I learned about JMockit while researching Java mocking frameworks in an effort to drive a project on which I was working to develop robust unit tests are part of normal code development. The key was what I adopted as our mantra for unit testing. By my definition, unit tests applied to code under test had to be isolates strictly to the target code. It was ok if the code under test reached out to other code as long as it didn't require filesyste/database support, web server support or any other support that required any kind of external setup. The tests needed to be able to run locally as part of Eclipse builds, manually in Eclipse and as part of any external build such as in a continuous integration and build environment.

What I found is that PowerMock/Mockito seemed to have a hard time dealing with static methods and initializers. The fact that we were required to use the IBM JRE only made things more difficult, especially with parts of our legacy Java code base where we had hotspots of bad code-smells that we simply couldn't address. In the end, we were able to address all of our testing needs using JMockit. The biggest gotcha we hit was directly related to the IBM JRE. For some reason, it somehow prevented use from Mocking static methods in the System class and other classes in the JRE. We worked around this by identifying methods that were making these unmockable calls and mocked them instead. A great exercise if you like reverse engineering with a blindfold.

JMockit should be able to easily handle your situation where you want to mock the parent method to allow you to isolate the code under test even from that method, which is a key factor in any kind of unit testing; test the target code in complete isolation so you can exercise every code path, including exception handling, to validate correctness. Jmockit allows you to mock classes and record/verify expectations. It's 'language' semantics are quite different from that of PowerMock/Mockito and takes a little getting used to if you are already familiar with PowerMock/Mockito.

Given the example in your OP, you wanted to be able to prevent the parent method from throwing exceptions. I would say that you want to establish 'happy-path' tests where no exceptions are thrown and tests where exceptions are thrown so you can validate your own exception handling. If you just rethrow them or let them percolate, then there's no need to bother with error-path tests for this particular method.

Here's an example of how you'd mock the parent class. Note that you do this IN your unit test code. There is no need to create any mock classes of your own whatsoever.


 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic