开发者

How can a static method return a different implementation class?

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.


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".


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:

  • EasyMock - http://easymock.org/
  • jMock - http://www.jmock.org/
  • MockObjects - http://www.mockobjects.com/
  • jMockIt - https://jmockit.dev.java.net/
  • mockito - http://mockito.org/

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


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜