What's the best framework for creating mock objects in Java? Why? What are the pros and cons of each framework?
相关问题
- Delete Messages from a Topic in Apache Kafka
- Jackson Deserialization not calling deserialize on
- How to maintain order of key-value in DataFrame sa
- StackExchange API - Deserialize Date in JSON Respo
- Difference between Types.INTEGER and Types.NULL in
The best solution to mocking is to have the machine do all the work with automated specification-based testing. For Java, see ScalaCheck and the Reductio framework included in the Functional Java library. With automated specification-based testing frameworks, you supply a specification of the method under test (a property about it that should be true) and the framework generates tests as well as mock objects, automatically.
For example, the following property tests the Math.sqrt method to see if the square root of any positive number n squared is equal to n.
When you call
propSqrt.check()
, ScalaCheck generates hundreds of integers and checks your property for each, also automatically making sure that the edge cases are covered well.Even though ScalaCheck is written in Scala, and requires the Scala Compiler, it's easy to test Java code with it. The Reductio framework in Functional Java is a pure Java implementation of the same concepts.
I like JMock because you are able to set up expectations. This is totally different from checking if a method was called found in some mock libraries. Using JMock you can write very sophisticated expectations. See the jmock cheat-sheat.
For something a little different, you could use JRuby and Mocha which are combined in JtestR to write tests for your Java code in expressive and succinct Ruby. There are some useful mocking examples with JtestR here. One advantage of this approach is that mocking concrete classes is very straightforward.
I am the creator of PowerMock so obviously I must recommend that! :-)
PowerMock extends both EasyMock and Mockito with the ability to mock static methods, final and even private methods. The EasyMock support is complete, but the Mockito plugin needs some more work. We are planning to add JMock support as well.
PowerMock is not intended to replace other frameworks, rather it can be used in the tricky situations when other frameworks does't allow mocking. PowerMock also contains other useful features such as suppressing static initializers and constructors.
I've been having success with JMockit.
It's pretty new, and so it's a bit raw and under-documented. It uses ASM to dynamically redefine the class bytecode, so it can mock out all methods including static, private, constructors, and static initializers. For example:
It has an Expectations interface allowing record/playback scenarios as well:
The downside is that it requires Java 5/6.
I've had good success using Mockito.
When I tried learning about JMock and EasyMock, I found the learning curve to be a bit steep (though maybe that's just me).
I like Mockito because of its simple and clean syntax that I was able to grasp pretty quickly. The minimal syntax is designed to support the common cases very well, although the few times I needed to do something more complicated I found what I wanted was supported and easy to grasp.
Here's an (abridged) example from the Mockito homepage:
It doesn't get much simpler than that.
The only major downside I can think of is that it won't mock static methods.