views:

263

answers:

1

This comparison shows, that JMockit has several advantages over other frameworks.

Are there also any advantages that one of the others (JMock, EasyMock, Mockito, Unitils, PowerMock + Mockito/EasyMock) has over JMockit?

+1  A: 

Three drawbacks:

  • You must use a Java agent to do bytecode instrumentation.
  • You can't use the signed junit.jar file shipped with Eclipse.
  • You have to learn a mock API. (In contrast to a stub object)

You can always discuss if it's a good thing to be able to mock a final class like JMockit can. Unless it's legacy code, refactoring is usually a better alternative.

With IDEs like Eclipse, I find myself using tool support to generate stubs inside the test class more frequently than mocking in the recent time. The advantage with this approach is that it's very simple. This is especially nice when you have a team with many developers and some of them don't like testing and have little motivation to learn a mocking framework. Also, stub implementations don't have framework limitations!

If you're open for stubbing as an alternative, you should check out Robert C. Martin's blog about mocking and stubbing here and here

Else, it looks very good! Although I have only experience with JMock, EasyMock and basic knowledge with JMockit.

Espen
Yeah, I'm also asking myself, how far I want to go with mocking. My own code uses Dependency Injection throughout, so mocking isn't really a complex task (though I don't always use interfaces for everything due to the added maintenance effort + performance overhead when used with GWTRPC). When you say you use tool support to generate stubs in Eclipse - which tools do you have in mind?
Chris Lercher
Just the core Java support in Eclipse. For example if you create a private or anonymous class that implements the interface you want to stub, then Eclipse can create a skeleton implementation. Just click <Ctrl> + 1 after you have selected the class.
Espen
Ah, ok - I thought maybe there's some tool that keeps the stub in sync, when the code changes or something.
Chris Lercher
1) What exactly you mean by "must use a Java agent"? (The "-javaagent" parameter is optional with JDK 1.6.)2) Correct about the signed JUnit jar, but it's just as easy to use the "real" JUnit as a "User library".3) Of course you have to learn a mocking API! The same is true for all other mocking/stubbing APIs in that comparison matrix... what's your point?
Rogerio
@Rogerio: Did you read the title of the question? It's not about if JMockit is a good framework or not. It is if it has any drawbacks at all. I personally like mocking and JMockit looks at least from the specification to be the best alternative. 3) I compare a mock API against stub **objects** (not stub API). And added some links you obviously didn't bother to read before you gave me -1. In some situations, a simple stub object is sufficient. My minor complaints on this questions just says the framework is really good. So keep up the good work on the project!
Espen
@Espen: Yes, I read not only the title but the whole question. And I read those two articles months ago, but they are hardly relevant here. Please note it's *not* about "any drawbacks at all", but whether JMockit has drawbacks that the *other tools in the comparison matrix don't*, and which should be *added* to the matrix. At least, that's what I understand the intent behind the question was. Your answer, however, doesn't seem to address that, as it talks about *not using a mocking API at all*. BTW, creating stubs by hand (or through an IDE) is full of limitations - not a viable alternative.
Rogerio
@Espen: note I have written two responses to the first article referenced, back in January...
Rogerio
@Rogerio: Is a stub created by hand full of limitations? I can not see any limitations except those given by Java itself. And since it is plain Java, it's nothing new to learn! Comparing mock frameworks, I will still say using a javaagent with Java 5 is a minus. Just a little one though.. And since JMockit is a very powerful framework, it also forgives bad design. Which is both good and bad. As I have tried to say the whole time, JMockit looks like a great framework. My major point was that plain stub objects in many situations removes the dependencies without learning a new mock framework.
Espen
@Rogerio: JMockit is fantastic, and it's very much possible, that I will use it someday. Will there be an abbreviated version of the JMockit documentation? (hint: All that's important about Mockito can be learnt in less than two hours...) Maybe together with defining a subset of JMockit features, that are marked "safe for good design" (this includes mocking final methods BTW!) That would help, because if we can test everything, it becomes a lot harder to convince team members (or - I'm afraid - even myself) to write good, reusable code without hidden or unnecessary dependencies!
Chris Lercher
@Espen: Yes, a hand-coded stub or mock *is* limited, when compared to an equivalent object created by a good mocking library. And such limitations have *nothing* to do with Java, either the language or the JVM. For example, it *forces* the tested class to provide some way for the test to pass the mock in: you shouldn't have to add complexity to the tested code in order to write unit tests. Another limitation is that you cannot write a stub for a final POJO class (one which does not implement a separate interface). Neither can you stub/mock constructors or static methods.
Rogerio
JMockit does not "forgive" bad design, anymore than any other Java library. You can't prevent bad code by imposing arbitrary technical limitations on developers, nor is the place of reusable APIs to do that. Such tools and APIs are about *enabling* developers to produce better software, not about constraining them to follow some supposed "right path" dictated by others. To me, and I have written about this elsewhere, the freedom to fully use the Java language, including `final` classes/methods, constructors, the `new` operator, `static` methods, etc. is non-negotiable.
Rogerio
There is already an "abbreviated" version of the JMockit documentation, the ["Getting Started" page](http://jmockit.googlecode.com/svn/trunk/www/installation.html).It's quick to read and should give a new user enough information to start writing tests. Also, the API javadocs contain links to relevant sections in the Tutorial and to sample tests, so it should be easy to learn more as you code from inside a Java IDE.
Rogerio
Comments from others above imply that a public Java class which 1) does not implement a separate Java interface, and 2) is marked `final` would somehow constitute "bad design". This is non-sense, with no supporting evidence in programming literature (that I can find, anyway). And no, the GoF book does not say that a class *must* implement a separate interface, if you're thinking of the "program to an interface, not an implementation" principle (one that I always follow, BTW). Marking a class `final` is considered good design if such a class is not designed for inheritance (see Effective Java).
Rogerio
@Rogerio: For those situations you're mention here and many others, a mock framework is often the best choice. But sometimes it can also be better to refactor the code and the need for a powerful framework like JMockit isn't longer necessary. All I say is that it is several solutions and strategies. Complex code should be written in methods that implements an interface. That's my personal opinion at least.
Espen
@Rogerio: Remember that you as a author of JMockit can not be totally objective. And you as an expert on mocking will have better results with mocking than a developer relatively new to Java. Anyway, it's my last comment on this post.. I will follow JMockit further and most possibly use it on my next project. My impression so far of JMockit is very good! Absolutely nothing of what Crhis and I have written is about bad functionality or API in JMockit. It is about mocking vs stubbing and strategies to achieve good design on your code with many developers on different skills levels.
Espen