编写优秀的单元测试(四)测试替身

本文详细介绍了单元测试中的测试替身,包括桩、伪造对象、测试间谍和模拟对象,强调了它们在隔离被测试代码、加速执行测试、确保测试确定性和模拟特殊情况下起到的作用,并通过实例分析阐述了如何选择和使用测试替身。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

一说到测试替身,我们总会不由自主的想到mock,我们在上一章简单提了一下,测试替身是 桩(Stub) 伪造对象(fake)测试间谍(spy) 模拟对象(mock)的总称。而使用测试替身的根本目的是使用替身替换一个模块的真实协作者,以期隔离被测试对象。

我们说,引入测试替身的根本原因就是:将测试代码和周围隔离开。

下面我们先分别看一下几种类型的测试替身:

测试替身的类型1:桩

桩(Stub) 测试桩是单元测试中常用的技术,我们经常能看到所谓的“打桩”。桩是指用最简单的代码来替代真实实现。

换句话说,如果A依赖了B的一个很复杂的方法的返回值,而我们要测试A,这个返回值是多少我们并不太关心,就可以写出一个B1(桩函数),只是用了B的桩而不是B,这样就可以完成测试,这里我们注意,使用桩可以达到下面三个效果:

  1. 隔离。如果A依赖了B,B依赖了C D,通过对于B打桩,就切断了A和C D的联系
  2. 补齐。如果A依赖了B,而B是其他语言写的,或者必须依赖某运行环境,就可以对B打桩替代B,让A可以运行下去
  3. 控制。如果A依赖B的某个返回值,通过对B打桩,直接设定返回值可以让A运行下去。

我们看一个桩的例子:假设我们要测试的类A需要向服务器写入日志,写日志需要调用继承自ILogger的实现的Log方法,而写入日志需要服务器的支持,那我们想要测试A,就可以对于测试的对象“打桩”。

public class LoggerStub : ILogger
{
    public LogLevel GetLevel()
    {
        return LogLevel.WRAN;
    }

    public void Log(LogLevel level, string message)
    {
    }
}

如上面的代码,LoggerStub就是一个测试桩,他是ILogger的最简单实现,既不调用服务器打印日志,也不做任何事情,仅仅是为了A的测试而存在,当然这适用于要测试A而不关心打印什么日志的情况。

测试替身的类型2:伪造对象

伪造对象是真实协作者的简单版本,它看起来像鸭子,叫起来像鸭子,却不是鸭子本身。

我们举个例子说,如果我们的数据存储在一个大型的数据库中,数据库给我们提供了API,但是这个数据库本身需要部署环境,需要有网络&

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值