EasyMock tutorial – Getting Started
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.
No comments:
Post a Comment