Mocking objects is not a new concept, especially when you want to test classes which refers complex objects you will end up constructing these objects by hard coded values! There are many open source frameworks available for mocking objects in your test classes, but here I am going to explain how we can mock your WebService client.
Before we begin, let me give you an introduction to object mocking.
The steps involved are:
The following files will be generated:
So, our WebService client is ready!
So, you have a WebService client and a test class for the dotNET WebService. Assume the provider charges you each time you invoke the service or the service is available only for a few hours. Your build will fail to test this service and thus you cannot proceed with your development. You have an option to add @Ignore annotation to the test class or method but how to proceed if other test classes are dependent on the result returned by the WebService?
Here, we are getting an instance of StockQuoteSoap from StockQuote, so let us mock StockQuoteSoap. Don't forget to import Mockito.
Before we begin, let me give you an introduction to object mocking.
What is Mocking?
Mocking is nothing but mimicking behaviours of real objects in a controlled way. Normally we mock objects which are complex in nature, to test the behaviour of other objects.Why mocking objects?
There are many reasons for mocking objects such as- constructing an object is too complex, many dependencies
- takes much time to return the results
- behaviour is not predictable
What are the popular mocking frameworks in Java?
There are many open source frameworks available in Java such as- jMock
- EasyMock
- Mockito
- SevenMock
- JMockit
- rMock
- Unitils
Mocking a .NET WebService
Let us use the .NET StockQuote WebService available under http://www.webservicex.net/stockquote.asmxThe steps involved are:
- generate stubs
- write a client for the stock quote WebService
- write a jUnit test class
- mock the client with Mockito
- test the client
Generating JAX-WS Stubs
Let us use wsimport to generate JAX-WS stubs:wsimport -verbose -p com.techmindviews.webservice.stockquote -Xnocompile -target 2.1 http://www.webservicex.net/stockquote.asmx?wsdl
The following files will be generated:
com\techmindviews\webservice\stockquote\GetQuote.java com\techmindviews\webservice\stockquote\GetQuoteResponse.java com\techmindviews\webservice\stockquote\ObjectFactory.java com\techmindviews\webservice\stockquote\StockQuote.java com\techmindviews\webservice\stockquote\StockQuoteSoap.java com\techmindviews\webservice\stockquote\package-info.java
Writing WebService client
Let us write a client for the StockQuote service, let us name it StockQuoteClient.javapublic class StockQuoteClient { private static StockQuoteClient INSTANCE; private static StockQuoteSoap stockQuoteSoap; public static StockQuoteClient getInstance(String wsdlURL) { if(INSTANCE == null) INSTANCE = new StockQuoteClient(); StockQuote stockQuote = new StockQuote(new URL(wsdlURL), new QName("http://www.webserviceX.NET/", "StockQuote")); this.stockQuoteSoap = stockQuote.getStockQuoteSoap(); return INSTANCE; } public String getQuote(String quoteID) { return stockQuoteSoap.getQuote(quoteID); } }
So, our WebService client is ready!
Writing test case for the WebService Client
Let us write a test class for the client:@RunWith(JUnit4.class) public class StockQuoteClientTest { @org.junit.Test public void testStockQuote() { StockQuoteClient stockQuoteClient = StockQuoteClient.getInstance("http://www.webservicex.net/stockquote.asmx?WSDL"); String quote = stockQuoteClient.getQuote("GOOG"); System.out.println("Stock Quote for Google:"+quote); } }
So, you have a WebService client and a test class for the dotNET WebService. Assume the provider charges you each time you invoke the service or the service is available only for a few hours. Your build will fail to test this service and thus you cannot proceed with your development. You have an option to add @Ignore annotation to the test class or method but how to proceed if other test classes are dependent on the result returned by the WebService?
Mocking the client and testing
Mockito is a simpler and better mocking API which is capable of mocking concrete classes as well as interfaces. Just include the maven dependency in your pom.xml file:<dependency> <groupid>org.mockito</groupId> <artifactid>mockito-all</artifactId> <version>1.9.0</version> </dependency>What to mock?
Here, we are getting an instance of StockQuoteSoap from StockQuote, so let us mock StockQuoteSoap. Don't forget to import Mockito.
import static org.mockito.Mockito.*; this.stockQuoteSoap = mock(StockQuoteSoap.class); when(stockQuoteSoap.getQuote(anyString())) .thenReturn("<stockquotes> <stock> <symbol>GOOG</Symbol> <last>629.64</Last> <date>1/12/2012</Date> <time>4:00pm</Time> <change>0.00</Change> <open>N/A</Open> <high>N/A</High> <low>N/A</Low> <volume>100</Volume> <mktcap>203.9B</MktCap> <previousclose>629.64</PreviousClose> <percentagechange>0.00%</PercentageChange> <annrange>473.02 - 670.25</AnnRange> <earns>29.337</Earns> <P-E>21.46</P-E><name>Google Inc.</Name> </Stock> </StockQuotes>");That's it! Whenever you invoke the getQuote() method of StockQuoteClient, the pre-defined XML will be returned! You can customize this code to read the XMLs from file system based on the string passed.