使用隔离框架构造伪对象进行单元测试

发表于:2012-9-18 10:54

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

 作者:Jeff Wong    来源:51Testing软件测试网采编

  一、伪对象

  1、简单的业务场景

  有一个文件监控程序,有一个方法用来检查文件名的合法性,检查过程中,如文件名不合法,需调用远程web服务记录日志,如远程web服务调用发生异常,发送邮件到指定收件人(类似这句话描述的业务场景在实际开发中数不甚数)。

  2、什么是伪对象

  上面所举的业务场景,文件监控主体程序是需要自己实现的,而远程web服务以及邮件服务都是监控程序所依赖的外部服务,在我们开发测试的时候可能还不能直接调用,或者调用服务代价太大(想想为什么代价比较大?),这个时候我们如何进行测试呢?

  答案是构造伪对象(fake object)来代替外部依赖的服务,伪对象就是桩对象和模拟对象的统称。

  在我们这个业务场景中,显然需要构造两个伪对象,即最常用的两个基础服务:日志和邮件服务。

  (1)桩对象(stub)

  定义:桩对象是对系统中现有依赖项的一个替代品,可人为控制,通过使用桩对象,无需涉及依赖项,即可直接对代码进行测试。

  和被测试对象的关系:

  从上图可知,桩对象在单元测试中是不会被下断言的。

  (2)模拟对象(mock)

  定义:模拟对象用来决定一个单元测试是通过还是失败。它通过验证被测试对象和伪对象之间是否进行预期的交互来判断。

  和被测试对象的关系:

  从上图可知,模拟对象在单元测试中必然要被下断言。

  综上所述,我们可以分析在当前所举的场景中,如果不对web服务伪对象验证测试结果(即不对它进行断言),而只是用来确保测试正确运行,那么日志服务就是一个桩对象;如果我们需要针对邮件服务来做断言,验证它是否被正确调用,那么邮件服务就是一个模拟对象。

  下面就手动创建两个伪对象,其中日志服务为桩对象,邮件服务为模拟对象,代码如下:

  a、LogService

using System;

namespace MonitorService
{
    public interface ILogService
    {
        Exception ExToThrow { get; set; }

        /// <summary>
        /// 记录日志
        /// </summary>
        /// <param name="msg"></param>
        void AppendLog(string msg);
    }

    public class StubLogService : ILogService
    {
        public Exception ExToThrow { get; set; }

        /// <summary>
        /// 记录日志
        /// </summary>
        /// <param name="msg"></param>
        public void AppendLog(string msg)
        {
            if (ExToThrow != null)
            {
                throw ExToThrow;
            }
            //throw new NotImplementedException("fake exception");
        }
    }
}

41/41234>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

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

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

沪ICP备05003035号

沪公网安备 31010102002173号