Wednesday, October 30, 2013

EasyMock tutorial – Getting Started

07.11.2012
 | 16317 views | 
  • submit to reddit
In this post, I’m going to show you what EasyMock is and how you can use it for testing your java application. For this purpose, I’m going to create a simple Portfolio application and test it using JUnit & EasyMock libraries.
Before we begin, lets first understand the need behind using EasyMock. Lets say, you are building an Android mobile application for maintaining user’s stock portfolios. Your application would use a stock market service to retrieve stock prices from a real server (such as NASDAQ).
When it comes to testing your code, you wouldn’t want to hit the real stock market server for fetching the stock prices. Instead, you would like some dummy price values. So, you need to mock the stock market service that returns dummy values without hitting the real server.
EasyMock is exactly doing the same – helps you to mock interfaces. You can pre-define the behavior of your mock objects and then use this mock object in your code for testing. Because, you are only concerned about testing your logic and not the external services or objects. So, it makes sense mock the external services.
To make it clear, have a look at the below code excerpt (we’ll see the complete code in a while):
1.StockMarket marketMock = EasyMock.createMock(StockMarket.class);
2.EasyMock.expect(marketMock.getPrice("EBAY")).andReturn(42.00);
3.EasyMock.replay(marketMock);
In the first line, we ask the EasyMock to create a mock object for our StockMarket interface. And then in the second line, we define how this mock object should behave – i.e., when the getPrice() method is called with the parameter “EBAY”, the mock should return 42.00. And then, we call the replay() method, to make the mock object ready to use.
So, that pretty much set the context about the EasyMock and it’s usage. Let’s dive into our Portfolio application.
You can download the complete source code from Github.

Portfolio application

Our Portfolio application is really simple. It has a Stock class to represent a stock name and quantity and the Portfolio class to hold a list of stocks. This Portfolio class has a method to calculate the total value of the portfolio. Our class uses a StockMarket (an interface) object to retrieve the stock prices. While testing our code, we will mock this StockMarket using EasyMock.

Stock.java

A very simple Plain Old Java Object (POJO) to represent a single stock.
01.package com.veerasundar.easymock;
02. 
03.public class Stock {
04. 
05.private String name;
06.private int quantity;
07. 
08.public Stock(String name, int quantity) {
09.this.name = name;
10.this.quantity = quantity;
11.}
12. 
13.public String getName() {
14.return name;
15.}
16. 
17.public void setName(String name) {
18.this.name = name;
19.}
20. 
21.public int getQuantity() {
22.return quantity;
23.}
24. 
25.public void setQuantity(int quantity) {
26.this.quantity = quantity;
27.}
28. 
29.}

StockMarket.java

An interface to represent a stock market service. It has a method that returns the stock price of the given stock name.
1.package com.veerasundar.easymock;
2. 
3.public interface StockMarket {
4.public Double getPrice(String stockName);
5.}

Portfolio.java

This object holds a list of Stock objects and a method to calculate the total value of the portfolio. It uses a StockMarket object to retrieve the stock prices. Since it is not a good practice to hard code the dependencies, we haven’t initialized the stockMarket object. We’ll inject it later using our test code.
01.package com.veerasundar.easymock;
02. 
03.import java.util.ArrayList;
04.import java.util.List;
05. 
06.public class Portfolio {
07. 
08.private String name;
09.private StockMarket stockMarket;
10. 
11.private List stocks = new ArrayList();
12. 
13./*
14.* this method gets the market value for each stock, sums it up and returns
15.* the total value of the portfolio.
16.*/
17.public Double getTotalValue() {
18.Double value = 0.0;
19.for (Stock stock : this.stocks) {
20.value += (stockMarket.getPrice(stock.getName()) * stock
21..getQuantity());
22.}
23.return value;
24.}
25. 
26.public String getName() {
27.return name;
28.}
29. 
30.public void setName(String name) {
31.this.name = name;
32.}
33. 
34.public List getStocks() {
35.return stocks;
36.}
37. 
38.public void setStocks(List stocks) {
39.this.stocks = stocks;
40.}
41. 
42.public void addStock(Stock stock) {
43.stocks.add(stock);
44.}
45. 
46.public StockMarket getStockMarket() {
47.return stockMarket;
48.}
49. 
50.public void setStockMarket(StockMarket stockMarket) {
51.this.stockMarket = stockMarket;
52.}
53.}
So, now we have coded the entire application. In this, we are going to test the Portfolio.getTotalValue() method, because that’s where our business logic is.

Testing Portfolio application using JUnit and EasyMock

If you haven’t used JUnit before, then it is a good time to Get started with JUnit.

PortfolioTest.java

01.package com.veerasundar.easymock.tests;
02. 
03.import junit.framework.TestCase;
04. 
05.import org.easymock.EasyMock;
06.import org.junit.Before;
07.import org.junit.Test;
08. 
09.import com.veerasundar.easymock.Portfolio;
10.import com.veerasundar.easymock.Stock;
11.import com.veerasundar.easymock.StockMarket;
12. 
13.public class PortfolioTest extends TestCase {
14. 
15.private Portfolio portfolio;
16.private StockMarket marketMock;
17. 
18.@Before
19.public void setUp() {
20.portfolio = new Portfolio();
21.portfolio.setName("Veera's portfolio.");
22.marketMock = EasyMock.createMock(StockMarket.class);
23.portfolio.setStockMarket(marketMock);
24.}
25. 
26.@Test
27.public void testGetTotalValue() {
28. 
29./* = Setup our mock object with the expected values */
30.EasyMock.expect(marketMock.getPrice("EBAY")).andReturn(42.00);
31.EasyMock.replay(marketMock);
32. 
33./* = Now start testing our portfolio */
34.Stock ebayStock = new Stock("EBAY"2);
35.portfolio.addStock(ebayStock);
36.assertEquals(84.00, portfolio.getTotalValue());
37.}
38. 
39.}
As you can see, during setUp() we are creating new Portfolio object. Then we ask EasyMock to create a mock object for the StockMarket interface. Then we inject this mock object into our portfolio object using portfolio.setStockMarket() method.
In the @Test method, we define how our mock object should behave when called, using the below code:
1.EasyMock.expect(marketMock.getPrice("EBAY")).andReturn(42.00);
2.EasyMock.replay(marketMock);
So, here after our mock object’s getPrice method would return 42.00 when called with EBAY.
Then we are creating a ebayStock with 2 quantities and add that to our portfolio. Since we setup the stock price of EBAY as 42.00, we know that the total value of our portfolio is 84.00 (i.e. 2 x 42.00). In the last line, we are asserting the same using the JUnit assertEquals() method.
The above test should run successfully if we haven’t made any mistakes in the getTotalValue() code. Otherwise, the test would fail.

Conclusion

So, that’s how we use the EasyMock library to mock the external services/objects and use them in our testing code. EasyMock can do much more than what I shown in this post. I’ll probably try to cover some advanced usage scenarios in my next posts.
Published at DZone with permission of Veera Sundar, author and DZone MVB. (source)

No comments: