您的位置:软件测试 > 开源软件测试 > 开源单元测试工具 >
EasyMock使用方法与原理剖析
作者:网络转载 发布时间:[ 2013/2/21 13:32:40 ] 推荐标签:

下面是示例代码中的一个接口 SalesOrder,它的实现类 SalesOrderImpl 的主要功能是从数据库中读取一个 Sales Order 的 Region 和 Total Price,并根据读取的数据计算该 Sales Order 的 Price Level(完整的实现代码都可以在 src.zip 中找到):

清单2:SalesOrder 接口

               
public interface SalesOrder
{
  ……
  public void loadDataFromDB(ResultSet resultSet) throws SQLException; 
  public String getPriceLevel();
}


其实现类 SalesOrderImpl 中对 loadDataFromDB 的实现如下:

清单3:SalesOrderImpl 实现

               
public class SalesOrderImpl implements SalesOrder
{
  ......
  public void loadDataFromDB(ResultSet resultSet) throws SQLException
  {
    orderNumber = resultSet.getString(1);
    region = resultSet.getString(2);
    totalPrice = resultSet.getDouble(3);
  }
  ......
}


方法 loadDataFromDB 读取了 ResultSet 对象包含的数据。当我们将之前定义的 Mock 对象调整为 Replay 状态,并将该对象作为参数传入,那么 Mock 对象的方法将会返回预先定义的预期返回值。完整的 TestCase 如下:

清单4:完整的TestCase

               
public class SalesOrderTestCase extends TestCase {
  public void testSalesOrder() {
    IMocksControl control = EasyMock.createControl();
    ......
    ResultSet mockResultSet = control.createMock(ResultSet.class);
    try {
      ......
      mockResultSet.next();
      expectLastCall().andReturn(true).times(3);
      expectLastCall().andReturn(false).times(1);
      mockResultSet.getString(1);
      expectLastCall().andReturn("DEMO_ORDER_001").times(1);
      expectLastCall().andReturn("DEMO_ORDER_002").times(1);
      expectLastCall().andReturn("DEMO_ORDER_003").times(1);
      mockResultSet.getString(2);
      expectLastCall().andReturn("Asia Pacific").times(1);
      expectLastCall().andReturn("Europe").times(1);
      expectLastCall().andReturn("America").times(1);
      mockResultSet.getDouble(3);
      expectLastCall().andReturn(350.0).times(1);
      expectLastCall().andReturn(1350.0).times(1);
      expectLastCall().andReturn(5350.0).times(1);
      control.replay();
      ......
      int i = 0;
      String[] priceLevels = { "Level_A", "Level_C", "Level_E" };
      while (mockResultSet.next()) {
        SalesOrder order = new SalesOrderImpl();
        order.loadDataFromDB(mockResultSet);
        assertEquals(order.getPriceLevel(), priceLevels[i]);
        i++;
      }
      control.verify();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}


在这个示例中,我们首先创建了 ResultSet 的 Mock 对象 moResultSet,并记录该 Mock 对象的预期行为。之后我们调用了 control.replay(),将 Mock 对象的状态置为 Replay 状态。 在实际的测试阶段,Sales Order 对象的 loadDataFromDB 方法调用了 mockResultSet 对象的 getString 和 getDouble 方法读取 mockResultSet 中的数据。Sales Order 对象根据读取的数据计算出 Price Level,并和预期输出进行比较。

对 Mock 对象的行为进行验证

在利用 Mock 对象进行实际的测试过程之后,我们还有一件事情没有做:对 Mock 对象的方法调用的次数进行验证。

为了验证指定的方法调用真的完成了,我们需要调用 verify 方法进行验证。和 replay 方法类似,您需要根据 Mock 对象的生成方式来选用不同的验证方式。如果 Mock 对象是由 org.easymock.EasyMock 类提供的 createMock 静态方法生成的,那么我们同样采用 EasyMock 类的静态方法 verify 进行验证:

verify(mockResultSet);


如果Mock对象是有 IMocksControl 接口所提供的 createMock 方法生成的,那么采用该接口提供的 verify 方法,例如第1节中的 IMocksControl 实例 control:

control.verify();


将对 control 实例所生成的 Mock 对象 mockConnection、mockStatement 和 mockResultSet 等进行验证。如果将上例中 expectLastCall().andReturn(false).times(1) 的预期次数修改为2,在 Eclipse 中将可以看到:

图3:Mock对象验证失败

Mock 对象的重用

为了避免生成过多的 Mock 对象,EasyMock 允许对原有 Mock 对象进行重用。要对 Mock 对象重新初始化,我们可以采用 reset 方法。和 replay 和 verify 方法类似,EasyMock 提供了两种 reset 方式:(1)如果 Mock 对象是由 org.easymock.EasyMock 类中的静态方法 createMock 生成的,那么该 Mock 对象的可以用 EasyMock 类的静态方法 reset 重新初始化;(2)如果 Mock 方法是由 IMocksControl 实例的 createMock 方法生成的,那么该 IMocksControl 实例方法 reset 的调用将会把所有该实例创建的 Mock 对象重新初始化。

上一页12345下一页
软件测试工具 | 联系我们 | 投诉建议 | 诚聘英才 | 申请使用列表 | 网站地图
沪ICP备07036474 2003-2017 版权所有 上海泽众软件科技有限公司 Shanghai ZeZhong Software Co.,Ltd