Прежде чем мы начнем, давайте сначала поймем необходимость использования EasyMock. Допустим, вы создаете мобильное приложение для Android для поддержки портфелей акций пользователей. Ваше приложение будет использовать сервис фондового рынка для получения цен акций с реального сервера (такого как NASDAQ).
Когда дело доходит до тестирования вашего кода, вам не захочется обращаться к реальному серверу фондового рынка для получения цен на акции. Вместо этого вам нужны фиктивные значения цен. Итак, вам нужно издеваться над сервисом фондового рынка, который возвращает фиктивные значения, не попав на реальный сервер.
EasyMock делает то же самое — помогает вам смоделировать интерфейсы. Вы можете заранее определить поведение ваших фиктивных объектов, а затем использовать этот фиктивный объект в своем коде для тестирования. Потому что вас интересует только тестирование ваша логика и не внешние услуги или объекты. Итак, имеет смысл издеваться над внешними сервисами.
Чтобы было понятнее, взгляните на приведенный ниже фрагмент кода (скоро мы увидим полный код):
1
2
3
|
StockMarket marketMock = EasyMock.createMock(StockMarket. class ); EasyMock.expect(marketMock.getPrice( 'EBAY' )).andReturn( 42.00 ); EasyMock.replay(marketMock); |
В первой строке мы просим EasyMock создать фиктивный объект для нашего интерфейса StockMarket. И затем во второй строке мы определяем, как должен вести себя этот фиктивный объект — т.е. когда метод getPrice () вызывается с параметром «EBAY» , макет должен возвращать 42,00 . А затем мы вызываем метод replay () , чтобы сделать фиктивный объект готовым к использованию.
Итак, это в значительной степени определяет контекст о EasyMock и его использовании. Давайте погрузимся в наше приложение Portfolio . Вы можете скачать полный исходный код с Github .
Портфолио приложения
Наше приложение Портфолио действительно простое. Он имеет класс Stock для представления названия и количества акций и класс Portfolio для хранения списка акций. Этот класс Portfolio имеет метод для расчета общей стоимости портфеля. Наш класс использует объект StockMarket (интерфейс) для получения цен акций. При тестировании нашего кода мы будем издеваться над этим StockMarket, используя EasyMock.
Stock.java
Очень простой Plain Old Java Object (POJO) для представления одной акции.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
package com.veerasundar.easymock; public class Stock { private String name; private int quantity; public Stock(String name, int quantity) { this .name = name; this .quantity = quantity; } public String getName() { return name; } public void setName(String name) { this .name = name; } public int getQuantity() { return quantity; } public void setQuantity( int quantity) { this .quantity = quantity; } } |
StockMarket.java
Интерфейс для представления услуги фондового рынка. У него есть метод, который возвращает цену акции данного имени акции.
1
2
3
4
5
6
|
package com.veerasundar.easymock; public interface StockMarket { public Double getPrice(String stockName); } |
Portfolio.java
Этот объект содержит список объектов Stock и метод для расчета общей стоимости портфеля. Он использует объект StockMarket для получения цен акций. Так как не рекомендуется кодировать зависимости жестко, мы не инициализировали объект stockMarket . Мы добавим его позже, используя наш тестовый код.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
package com.veerasundar.easymock; import java.util.ArrayList; import java.util.List; public class Portfolio { private String name; private StockMarket stockMarket; private List<Stock> stocks = new ArrayList<Stock>(); * * this method gets the market value for each stock, sums it up and returns * the total value of the portfolio. * public Double getTotalValue() { Double value = 0.0 ; for (Stock stock : this .stocks) { value += (stockMarket.getPrice(stock.getName()) * stock .getQuantity()); } return value; } public String getName() { return name; } public void setName(String name) { this .name = name; } public List<Stock> getStocks() { return stocks; } public void setStocks(List<Stock> stocks) { this .stocks = stocks; } public void addStock(Stock stock) { stocks.add(stock); } public StockMarket getStockMarket() { return stockMarket; } public void setStockMarket(StockMarket stockMarket) { this .stockMarket = stockMarket; } } |
Итак, теперь мы закодировали все приложение. В этом мы собираемся протестировать метод Portfolio.getTotalValue () , потому что именно там находится наша бизнес-логика. Тестирование приложения-портфолио с использованием JUnit и EasyMock. Если вы ранее не использовали JUnit, то самое время начать работу с JUnit .
PortfolioTest.java
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
package com.veerasundar.easymock.tests; import junit.framework.TestCase; import org.easymock.EasyMock; import org.junit.Before; import org.junit.Test; import com.veerasundar.easymock.Portfolio; import com.veerasundar.easymock.Stock; import com.veerasundar.easymock.StockMarket; public class PortfolioTest extends TestCase { private Portfolio portfolio; private StockMarket marketMock; @Before public void setUp() { portfolio = new Portfolio(); portfolio.setName( 'Veera' s portfolio.'); marketMock = EasyMock.createMock(StockMarket. class ); portfolio.setStockMarket(marketMock); } @Test public void testGetTotalValue() { * = Setup our mock object with the expected values * EasyMock.expect(marketMock.getPrice( 'EBAY' )).andReturn( 42.00 ); EasyMock.replay(marketMock); * = Now start testing our portfolio * Stock ebayStock = new Stock( 'EBAY' , 2 ); portfolio.addStock(ebayStock); assertEquals( 84.00 , portfolio.getTotalValue()); } } |
Как видите, во время setUp () мы создаем новый объект Portfolio . Затем мы просим EasyMock создать фиктивный объект для интерфейса StockMarket . Затем мы внедряем этот фиктивный объект в наш объект портфолио, используя метод portfolio.setStockMarket () .
В методе @Test мы определяем, как должен вести себя наш фиктивный объект при вызове, используя следующий код:
1
2
|
EasyMock.expect(marketMock.getPrice( 'EBAY' )).andReturn( 42.00 ); EasyMock.replay(marketMock); |
Итак, вот после нашего метода getPrice нашего фиктивного объекта вернется 42.00 при вызове с EBAY .
Затем мы создаем ebayStock с 2 количествами и добавляем его в наше портфолио. Поскольку мы устанавливаем цену акции EBAY равной 42,00, мы знаем, что общая стоимость нашего портфеля составляет 84,00 (то есть 2 x 42,00). В последней строке мы утверждаем то же самое с помощью метода JUnit assertEquals () .
Вышеприведенный тест должен пройти успешно, если мы не допустили ошибок в коде getTotalValue () . В противном случае тест не пройден.
Вывод
Итак, вот как мы используем библиотеку EasyMock для насмешки внешних сервисов / объектов и использования их в нашем тестовом коде. EasyMock может сделать гораздо больше, чем я показал в этом посте. Возможно, я постараюсь рассказать о некоторых продвинутых сценариях использования в моих следующих постах.
Ссылка: учебное пособие по EasyMock — начало работы от нашего партнера по JCG Веры Сундар в блоге