参考案例:(本位使用markdown编写)
https://www.ibm.com/developerworks/cn/opensource/os-cn-easymock/
https://www.yiibai.com/easymock/
git.oschina实例:https://gitee.com/lhhTestTool/LhhEasyMock
# LhhEasyMock
# EasyMock
EasyMock便于无缝地创建模拟对象。它使用Java反射,以创造为给定接口的模拟对象。模拟对象是什么,只不过是代理的实际实现。
考虑如:股票服务的情况下,它返回一个股票价格的详细信息。在开发过程中,实际的库存服务不能被用于获得实时数据。
因此,我们需要一个虚拟的股票实施服务。简易模拟可以很容易理解顾名思义这样
# EasyMock的好处
* 不用手写 - 没有必要通过自己编写的模拟对象。
* 重构安全 - 重构接口方法的名称或重新排序的参数不会破坏测试代码在运行时创建。
* 返回值支持 - 支持返回值。
* 异常支持 - 支持例外/异常。
* 命令检查支持 - 支持检查命令方法调用。
* 注释支持 - 支持使用注解创建。
# EasyMock架包
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>RELEASE</version>
</dependency>
# 阶段介绍
## 数据准备阶段
```
//创建一个要测试的组合对象
Portfolio portfolio = new Portfolio();
//创建将要添加到组合中的数据(股票)列表。
List<Stock> stocks = new ArrayList<Stock>();
Stock googleStock = new Stock("1","Google", 10);
Stock microsoftStock = new Stock("2","Microsoft",100);
stocks.add(googleStock);
stocks.add(microsoftStock);
```
## Record 阶段
```
// Mock的Record 阶段 -》 在这个阶段,Record 状态,用户可以设定 Mock 对象的预期行为和输出,这些对象行为被录制下来,保存在 Mock 对象中
//创建提供数据(股票)服务的模拟对象
StockService stockService = EasyMock.createMock(StockService.class);
//模拟数据(股票)服务的行为,以返回各种方法的价值。设定return的返回值
EasyMock.expect(stockService.getPrice(googleStock)).andReturn(50.00);
EasyMock.expect(stockService.getPrice(microsoftStock)).andReturn(1000.00);
```
## Replay 阶段
`replay()`,将 Mock 对象的状态置为 `Replay 状态`。
```
//Mock的Replay 阶段 -》 在这个阶段,在使用 Mock 对象进行实际的测试前,我们需要将 Mock 对象的状态切换为 Replay。在 Replay 状态,Mock 对象能够根据设定对特定的方法调用作出预期的响应。
EasyMock.replay(stockService);
//在业务处理组合中增加数据项
portfolio.setStocks(stocks);
//在业务处理组合中增加数据服务
portfolio.setStockService(stockService);
```
## 测试调用阶段
```
//实际处理逻辑
double marketValue = portfolio.getMarketValue();
//验证数据处理 10*50.00 + 100* 1000.00 = 500.00 + 100000.00 = 100500
System.out.println("Market value of the portfolio: "+ marketValue);
```
## EasyMock 验证阶段(非必须)
```
//Mock的验证阶段 (验证调用过程正常完成)
EasyMock.verify(stockService);
```
# EasyMock 方法汇总
## EasyMock
构建和初始化
1.EasyMock静态方法createMock
> 使用 EasyMock 动态构建 Mock 对象
2.EasyMock静态方法createControl
> 能创建一个接口 IMocksControl 的对象,该对象能创建并管理多个 Mock 对象。
如果需要在测试中使用多个 Mock 对象,我们推荐您使用这一机制,
因为它在多个 Mock 对象的管理上提供了相对便捷的方法。
> 如果您要模拟的是一个具体类而非接口,那么您需要下载扩展包 `EasyMock Class Extension 2.2.2`。
在对具体类进行模拟时,您只要用 `org.easymock.classextension.EasyMock` 类中的静态方法代替 `org.easymock.EasyMock` 类中的静态方法即可。
3,replay(mockResultSet) or replay();
> 将 Mock 对象切换到 Replay 状态
两种使用方式:
eg
1.如果构建对象`IMocksControl`则调用它的`.replay()`;
2.如果构建对象为具体的我们业务测试对象,则调用`EasyMock.replay(xxx);`(本例调用这个)
4.verify(mockResultSet) or verify();
> 对 Mock 对象的行为进行验证
两种使用方式:
eg
1.如果构建对象`IMocksControl`则调用它的`.verify()`;
2.如果构建对象为具体的我们业务测试对象,则调用`EasyMock.verify(xxx);`(本例调用这个)
5.reset
> 为了避免生成过多的 Mock 对象,EasyMock 允许对原有 Mock 对象进行重用。要对 Mock 对象重新初始化,我们可以采用 reset 方法
两种使用方式:
eg
1.如果构建对象`IMocksControl`则调用它的`.reset ()`;
2.如果构建对象为具体的我们业务测试对象,则调用`EasyMock.reset (xxx);`(本例调用这个)
# IExpectationSetters
对 Mock 对象行为的添加和设置是通过接口 IExpectationSetters 来实现的
两种类型的输出:(1)产生返回值;(2)抛出异常。
1.IExpectationSetters<T> andReturn(T value);
> 设定返回值
2.void andStubReturn(T value);
> 有时,某个方法的调用总是返回一个相同的值,为了避免每次调用都为 Mock 对象的行为进行一次设定
3.IExpectationSetters<T> andThrow(Throwable throwable);
> 设定预期抛出异常
4.void andStubThrow(Throwable throwable);
> 设定抛出默认异常的函数 与 `andStubReturn` 类似
5.IExpectationSetters<T> times(int count);
> 该方法可以 Mock 对象方法的调用次数进行确切的设定
eg:
`andReturn("My return value").times(3);`
6. times(int minTimes, int maxTimes)
> 该方法最少被调用 minTimes 次,最多被调用 maxTimes 次
7.atLeastOnce()
> 该方法至少被调用一次。
8. anyTimes()
> 该方法可以被调用任意次。
eg:
`expect(mockResult.close()).times(3, 5);`
9.其他方式 参考文章
https://www.ibm.com/developerworks/cn/opensource/os-cn-easymock/
https://www.yiibai.com/easymock/