views:

157

answers:

4

I am writing a unit test by mocking out external services

com.example.Service service;

service = RealServiceClient.getService().getServiceId("1");

How can I simulate the above RealService class?

The thing is RealServiceClient.getService() returns RealService.

PS: I am new to Java.

+1  A: 

That's easy. Do not use singletons or other mutable statics. Pass in your service (or a way to get it) through the constructor, i.e. "Parameterise from Above".

Tom Hawtin - tackline
+1  A: 

There are quite a few options for creating a mock Service for a unit test. Most of these have 'mock' in the name and are frameworks for doing this sort of a thing. Here are a few Java based mock tools:

The other option is to modify you service itself to allow an alternate implementation to be supplied for testing. You may not have the luxury of modifying the service or interface though to allow this.

Personally, I prefer to use a dynamic language for doing the mocks. I find that you can get a lot of the ability you need without a fancy framework. I use groovy a lot for writing my unit tests. See this page for more information on using Groovy closures instead of Mocks: http://groovy.codehaus.org/Developer+Testing+using+Closures+instead+of+Mocks

Chris Dail
I find mockito the easier and nicest to use
notnoop
The correct url for JMockit is http://code.google.com/p/jmockit.You can do something similar to the Groovy closures with `MockUp` classes in JMockit, even if it's all Java.
Rogerio
+1  A: 

In addition to other mocking frameworks, I recommend Mockito. It is terrific. As a newbie to Java, it will take some time to go through the tutorials but it will be well worth effort.

However, as Pascal points out, Mockito cannot mock static methods. This is a major limitation for the example you provided.

Michael Easter
Mockito can not mock static methods on its own.
Pascal Thivent
A: 

If it is possible, make the code more testable as suggested by Tom Hawtin. Designing code for testability is actually a good practice so that would be a good idea. Some tips: eliminate static methods (thus avoid singletons), provide setters or constructor allowing to inject dependencies.

If it's not (e.g. it's legacy code that you can't change), use a mocking framework allowing to mock static methods. I'm thinking to JMockit or Powermock (the later extends EasyMock and Mockito and provides the ability to mock static methods). I've experimented Powermock recently and I had lots of fun using it.

Pascal Thivent