使用配置文件定义 Mock 对象,创建高效、灵活的测试用例

发表于:2007-10-30 12:13

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:郑闽睿 黄湘平    来源:网络转载

清单6:SalesOrder 接口
                
public interface SalesOrder
{
  ……
  public void loadDataFromDB(ResultSet resultSet) throws SQLException;	
  public String getPriceLevel();
}

  如果我们对 getPriceLevel 方法进行测试,就可以将该方法在正确运行下的预期输出抽象成 Mock 对象,并配置如下:


清单7:配置预期输出
                
<mockConfig>
  <mockObjects>
    <mockObject name="mockSalesOrder" mockedClass="xmleasymock.demo.test.SalesOrder" />
  </mockObjects>
  <mockBehaviors>
    <mockBehavior mockObject="mockSalesOrder" method="getPriceLevel">
      <paramValues />
      <ctrlOptions>
        <ctrlOption option="andReturn" value="expected result 1" times="1" />
        <ctrlOption option="andReturn" value="expected result 2" times="1" />
        ......
      </ctrlOptions>
    </mockBehavior>
  </mockBehaviors>
</mockConfig>

5.使用配置文件运行测试用例

  与在代码中动态构建 Mock 对象不同,XMLEasyMock 是在配置文件的解析过程中动态生成 Mock 对象的。因此,如果用户需要使用 Mock 对象,需要从解析模块中获取。XMLEasyMock 提供了一个工具类 EasyMockUtil,这个工具类提供了 findMockObjectByName 方法用于返回 Mock 对象。该方法的输入参数就是在配置文件的 <mockObject> 元素中配置的 name 属性。另外,我们在上文中提到,EasyMockUtil 提供了方法 loadConfig 用于装入配置文件,该方法的输入参数就是配置文件的路径。

  在 XMLEasyMock 提供的测试代码(SalesOrderTestCase.java)中,我们对 ResultSet 接口进行了模拟,从而对 SalesOrdergetPriceLevel 进行测试。在完成相关 Mock 对象的配置之后,我们可以通过 XMLEasyMock 提供的功能对测试用例实现如下:


清单8:完整的 TestCase
                
public class SalesOrderTestCase extends TestCase {
  public void testAfterConfig() {
    try {
      EasyMockUtil.loadConfig("/xmleasymock/demo/properties/mockConfig.xml");
      
      DBUtility mockDBUtility = 
              (DBUtility) EasyMockUtil.findMockObjectByName("mockDBUtility");
      Connection conn = mockDBUtility.getConnection();
      Statement stmt = conn.createStatement();
      ResultSet rs = stmt.executeQuery("select * from sales_order");
      
      SalesOrder realOrder = new SalesOrderImpl();
      SalesOrder mockOrder = 
              (SalesOrder) EasyMockUtil.findMockObjectByName("mockSalesOrder");
      
      while (rs.next()) {
        realOrder.loadDataFromDB(rs);
        assertEquals(realOrder.getPriceLevel(), mockOrder.getPriceLevel());
      }
      EasyMockUtil.verify();
      
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

  通常,在数据库连接模块中,开发人员都会开发一个类似于 DBUtitlity 的实现来获取数据库连接以及释放数据库资源。在我们的测试用例中,这不是必需的,但为了对真实的开发和测试环境进行模拟,我们也在 mockConfig.xml 中对 DBUtiltiy, ConnectionStatement 等接口进行了配置。我们通过 DBUtility Mock 对象的名称 "mockDBUtility" 获得 mockDBUtility 对象,并通过它得到 ResultSet 的 Mock 对象。在对 getPriceLevel 方法进行测试时,我们将预期结果抽象成 Mock 对象,它在配置文件中的名称是 mockSalesOrder。我们通过这个名称获得预期结果的 Mock 对象。最后,我们将实际结果和预期结果进行比对,从而完成测试。

6.结论

  我们通过配置文件对 Mock 对象进行定义,实现了测试数据和代码的分离,从而避免了将数据编码在代码中所带来的一系列不便。当测试数据或是测试用例发生变化时,开发或部署人员只需对配置文件作出改动,而不用修改测试代码和重新编译、部署,降低了测试用例发生变化所带来的工作量和时间花销。本文基于 EasyMock 实现了通过配置文件定义Mock对象的机制。实际上,读者可以基于任何的自己熟悉的 xMock 项目来实现这里的思想。

44/4<1234
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号