Mocking with JMockit
by Chris Wash on Jun.09, 2009, under Developer Testing, Java
Update: I cleaned up the example based on Rogerio’s comments.
Recently I stumbled onto JMockit and have been pretty impressed with the flexibility of the approach it takes.
Many mocking frameworks seem to take an elitist attitude toward testable code, not attempting to solve certain problems in favor of guiding one toward a more testable design. It appears JMockit is a response to this.
There’s no getting around the fact that some frameworks, especially legacy or proprietary third party modules, are not coded in such a way that it’s easy to write testable code against them. Common pain points include:
- Pervasive use of statics
- Lack of dependency injection mechanisms
- Creating dependencies inline with the “new” keyword
All of these issues will pose problems when trying to double-out dependent code for testing purposes. One approach to solve these problems is to use a dynamic language and metaprogramming constructs to do this kind of doubling. Testing Java code with JRuby or Groovy has become more and more popular for this very reason.
But a lot of these will introduce a level of language abstraction between your test code and the code under test, and you’ll have to have developers maintaining a test suite sign on to learn the language being used.
In comes JMockit, which uses the instrumentation features provided with Java5 to perform a lot of the same magic tricks for you.
This also allows you to test things that weren’t otherwise possible (or are very difficult) and overall I think the programming model is much more in-tune with standard Java programming idioms. It doesn’t discriminate against you if you don’t use dependency injection, but will work with you if you do. Here’s a quick example that colleagues Andy Pemberton and Patrick Cox worked through with me trying out JMockit.
public class ControllerTest {
@Mocked
HttpServletRequest mockHttpServletRequest;
@Mocked
ServiceRemote mockServiceRemote;
@Test
public void test_execute_expectations() {
new Expectations() {
{ /* define in static block */
final Model m = new Model();
m.setId(12345l);
mockHttpServletRequest.getParameter("modelId"); returns("12345");
mockServiceRemote.getModel(12345l); returns(m);
mockHttpServletRequest.setAttribute("model", m);
}
};
/* simulate setter injection */
Controller c = new Controller();
c.setHttpServletRequest(mockHttpServletRequest);
c.setServiceRemote(mockServiceRemote);
/* call code under test */
c.execute();
/* strict mode will throw exceptions! */
}
}
You can get the whole project from my GitHub account.

June 9th, 2009 on 11:00 pm
Nice! Good to see that release 0.98 is already being used 8^)
Your example test works fine, but two simplifications can be made.
First, the calls to “newEmptyProxy” are redundant, since JMockit already creates and assigns automatically an instance to each mock field.
Second, the call to “endRecording()” is no longer required in cases like this. JMockit will automatically switch from record to replay at the end of each Expectations initialization block.
June 11th, 2009 on 9:58 pm
@Rogerio – thanks for the advice – I’ll make these changes on the project in github. Any plans to get JMockit distros plugged into a remote Maven repo?
June 13th, 2009 on 8:05 pm
No plans regarding Maven or Ivy repositories yet…
I looked for an easy way to automate the upload to a Maven repo a few weeks ago, but could not find one.
If someone knows how to do it without some huge effort, I would appreciate it.
Thanks
February 24th, 2010 on 3:43 pm
Hi Chris,
I have a scenario where I have to write the TestCases using JMockit.
We are using JPF controllers for the portal applications.I have to write test cases for the JPF Controllers.Here the portal code is not allowed to hit any database directly instead we have to use the Application JAR in which there are methods which can hit the database.
I am in real confusion how to write jmockit test cases for this type of controllers..
Please help me
February 26th, 2010 on 2:16 am
@Vik
JMockit (or any mocking framework) will allow you to assert that the code that you call to hit the database actually gets called in your controller. Setting up the mocks and writing the test is going to depend on what you’re doing, but in general what you are going to want to do to test the controller is define expectations around the code you mentioned in your Application JAR that hits the database, and from your test you want to exercise your controller’s execute method. In my example I’m expecting the mockService to have its getModel method called and return a model object. You can set yours up simiarly. The controller also will be touching the HttpRequest which I have set up expectations for as well. Hope this helps!