Software developer, trainer, speaker (Java, JavaScript, Groovy, php, Cloud, DevOps, performance, architecture, motivational topics). I'm a passionate software developer. Software of best quality in the shortest possible time, that's my goal. Thomas has posted 6 posts at DZone. You can read more from them at their website. View Full User Profile

How to "Mock" Final Classes With Mockito

06.01.2010
| 17916 views |
  • submit to reddit

 If you are using mockito, then you cannot "mock" final classes. But there is a nice library called JDave which does some bytecode, i.e. CGLIB, magic to change final classes to non-final classes.

Just download JDave, add the JAR files to the classpath, and start your test cases with the following VM option:

-javaagent:your-library-directory\jdave-unfinalizer-1.1.jar

 

0
Your rating: None
Published at DZone with permission of its author, Thomas Eichberger.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Nicolas Frankel replied on Tue, 2010/06/01 - 10:56am

Seems PowerMock is also on the trend: it offers additional features and supports Mockito and EasyMock.

It works without agent but requires that you use its API that in turn calls the chosen framework.

Mladen Girazovski replied on Tue, 2010/06/01 - 11:44am

JDave can also be used with JMock2 (my preferred mock lib): http://www.jmock.org/mocking-classes.html

Mario Fusco replied on Tue, 2010/06/01 - 4:42pm

It looks great. Could be a good solution to overcome some of the biggest lambdaj limitations.

Thomas Eichberger replied on Wed, 2010/06/02 - 1:49am in response to: Mario Fusco

How good or usable is lambdaj? Will it be obsolete after introduction of closures into Java and (hopefully) adoptions of the collection classes?

Fabrizio Giudici replied on Wed, 2010/06/02 - 4:06am

As you know the closure debates is still in, with some light shed a couple of days ago. In any case, Java 7 won't be available before the end of the year and some time, even one more year, could pass before it's adopted to the point that you can move to it. For instance, I don't plan to move my projects to Java 7 before Spring / Summer 2011. I'm pretty sure that many industrial projects won't upgrade before a much longer time. In the meantime lambdaj works now.

Steven Devijver replied on Wed, 2010/06/02 - 4:10am

Makes you wonder what the point of testing is if you have to modify your classes. This is a useless hack and - to use Rod Johnson's words - a "sackable offence".

Thomas Eichberger replied on Wed, 2010/06/02 - 1:40pm in response to: Steven Devijver

Only the mock class is changed ("final" is removed), not the tested class. And that's ok.

Mladen Girazovski replied on Wed, 2010/06/02 - 5:48am in response to: Steven Devijver

Makes you wonder what the point of testing is if you have to modify your classes. This is a useless hack and - to use Rod Johnson's words - a "sackable offence".

 "You" do not have to modify your classes, the agent will do this for you on the fly.

Just imagine you want to mock out  some external dependency, i.e. a final class that comes with a framework that you do not control, if you can't mock it, you would have to change your design to include some kind of proxy that you could mock.

Kode Ninja replied on Wed, 2010/06/02 - 8:33am

JMockit also lets you mock final classes, and a whole lot more. With JMockit, almost no code is un-testable code. Here's the official tutorial. And another one that discusses the Annotations API.

Fabrizio Giudici replied on Wed, 2010/06/02 - 9:08am in response to: Mladen Girazovski

I understand that governor, when he says "modify", is not concerned about the way you do that, but about the point that you're testing a thing that is different than the production. Generally speaking, is right - but remember that here we're talking of modifying classes for creating a mock - I mean, the mock is not production code by definition! Who cares how it has been generated?

Alessandro Santini replied on Wed, 2010/06/02 - 4:02pm in response to: Fabrizio Giudici

Fabrizio,

do not take me as a nitpicker - as the Liskov substitution principle requires, it is not production codes but it must behave exactly as if it were.

Mario Fusco replied on Mon, 2010/06/07 - 2:56am in response to: Thomas Eichberger

I'm not the right person to say if lambdaj is good or usable since I'm its developer :)

To reply to your second question, the adoption of Java 7 will for sure make obsolete the closures part of the project and honestly I'm happy for that. Java definitively deserves better functional capabilities than the one provided by lambdaj. As for the collections part I don't think that the new Java 7 closures will be immediately used in the collection framework or at least I'm currently not aware of anybody working on it. Anyway, even in this case, some lambdaj's ideas could be recycled to build a DSL in order to make the code that manipulates collections more readable.

Hontvári Levente replied on Mon, 2010/06/07 - 3:07pm in response to: Kode Ninja

Yes, JMockit also uses the java agent technique. If we compare the two, Mockito is easy to learn, JMockit is powerful. If you manage to set it up correctly, JMockit can mock anything imaginable, including instances created with "new" in third party libraries.

Fabrizio Giudici replied on Thu, 2010/06/17 - 7:06pm in response to: Alessandro Santini

Liskov is a design principle and talks about contracts and behaviors; I don't think it relates to 'final' which is a language thing. In other words, 'final' doesn't change the behavior of things.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.