与protected成员有关的单元测试方式

这是一篇简单的文章,讨论了单元测试中遇到protected成员的应对方案。此外,在文章最后也希望和大家讨论一下某个特殊的情况下的处理方法。

protected是一个有趣而有用的修饰符,它把方法的访问成员严格限制在自身或自己的子类身上。换句话说,在使用过程中,protected成员对外部是开放的(因为其他类可以通过继承来使用该成员),又是封闭的(不是自身或子类的一切成员都无法访问)。而对于单元测试来说,protected成员又是尴尬的,因为它的“开放”意味着我们必须对它进行单元测试,而“封闭”又阻碍了我们在单元测试中涉及protected成员。

测试protected方法

现在有一个类,其中包含一个protected方法:

public class SomeClass
{protected int SomeMethod(string arg) { ... }
}

如果我们需要对这个protected方法进行单元测试,可以在测试代码中准备一个辅助类型:

public class SomeClassForTest : SomeClass
{public int PublicSomeMethod(string arg){return this.SomeMethod(arg);}
}

于是在单元测试中,便可以通过调用PublicSomeMethod来测试基类的SomeMethod方法:

var testClass = new SomeClassForTest();
var result = testClass.PublicSomeMethod(null);
Assert.Equal(0, result);

非常简单。

如果您觉得麻烦,也可以将SomeClass类中的SomeMethod方法改为protected internal,这样便可以在InternalVisibleTo的测试程序集中使用了。不过,我觉得为单元测试而改变成员的访问级别不是一个合适的做法。

对protected方法进行Mock

现在有一个类,其中有一个protected方法:

public class SomeClass
{protected virtual int SomeMethod(string arg) { ... }
}

并且,某个被测试的方法接受SomeClass作为参数。虽然被测试的方法不会直接调用SomeMethod方法,但是SomeMethod的实现会影响到公开接口的表现形式。于是,我们需要对SomeMethod进行Mock或Stub。为此,我们同样需要准备一个辅助类型:

public class MockSomeClass : SomeClass
{protected override int SomeMethod(string arg){return this.PublicSomeMethod(arg);}public virtual int PublicSomeMethod(string arg){return base.SomeMethod(arg);}
}

在MockSomeClass中,我们覆盖了基类的SomeMethod实现,使它调用了子类中公开的PublicSomeMethod方法,而PublicSomeMethod内部又调用了基类的SomeMethod方法。因此,如果您不去进行任何处理,那么MockSomeClass会保持SomeMethod的实现不变。而如果您需要对SomeMethod进行Mock或Stub的时候,便可以从PublicSomeMethod下手:

Mock<MockSomeClass> mockSomeClass = new Mock<MockSomeClass>() { CallBase = true };
mockSomeClass.Setup(c => c.PublicSomeMethod("123")).Returns(123);DoSomeTest(mockSomeClass.Object); // use the mock object

也很容易。

为了可测试性

值得注意的是,为了“可测试性”,第二部分中的protected方法必须是virtual的,因为我们需要在子类中进行override。同理,Mock框架能够辅助的方法也必须是virtual的,即使是一个public方法。那么,您觉得这是为了可测试性而做出的让步吗?或者换句话说,您觉得,一个不可以override的protected方法,但是会影响到其他公开接口的功能,这是不是一个合理的设计呢?如果这是一个合理的设计,又不想作出这样的让步……我们又该怎么做呢?

关于这点,我有自己的想法,不过还是想先听一下您的意见。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/268446.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机画面的音乐素材,音效素材:高科技用户界面UI点触计算机数据分析全息音效合集...

音效素材&#xff1a;高科技用户界面UI点触计算机数据分析全息音效合集包含1000多组模块化用户界面音效&#xff0c;由最好的制造商“EURORACK”亲自录制。MODULAR UI是由世界著名的音响设计师和音乐家理查德迪瓦恩共同创建的一个用户界面音效库。设计并完全由理查德迪瓦恩的个…

cacti安装FAQ

为什么80%的码农都做不了架构师&#xff1f;>>> CACTI中MSN和EMAIL不能同时预警 描述 CACTI中使用thold可以实现邮件的预警&#xff0c;超过阀值的时候&#xff0c;基本上可以在半个小时之内把邮件发出来&#xff0c;这种方式是比较稳定的方式。 另外可以使用MSN…

初中计算机新课标培训心得,新课标学习心得体会

新课标学习心得体会由好范文网的会员投稿精心推荐&#xff0c;小编希望以下6篇范文对你的学习工作能带来参考借鉴作用。第1篇&#xff1a;新课标学习心得体会新课标学习心得体会怎么写&#xff1f;以下是我们给你的范文格式参考。用课余时间我认真学习了中心校下发的小学品德与…

利用原生js做数据管理平台

摘要&#xff1a;数据管理平台在当今社会中运用十分广泛&#xff0c;我们在应用过程中&#xff0c;要对数据进行存储&#xff0c;管理&#xff0c;以及删除查询等操作&#xff0c;而我们在实际设计的时候&#xff0c;大牛们大多用到的是JQuery&#xff0c;而小白对jq理解也较困…

ios 阅览器html5,HTML5测试:iOS 8浏览器Safari提升明显

没错&#xff0c;日前&#xff0c;国外著名手机网站GSMArena就发现iOS 8中的Safari浏览器确实增强了对HTML5的支持。如下图所示&#xff0c;在HTML5test.com的数据库中&#xff0c;新版本Safari得到的分数为440(满分为550)&#xff0c;相比iOS 7中的Safari的412分来说还是有不小…

RAID冗余技术的介绍AND实现

一、RAID技术规范简介 RAID技术主要包含RAID 0&#xff5e;RAID 7等数个规范&#xff0c;它们的侧重点各不相同&#xff0c;常见的规范有如下几种&#xff1a; RAID 0&#xff1a;RAID 0连续以位或字节为单位分割数据&#xff0c;并行读/写于多个磁盘上&#xff0c;因此具有很高…

计算机原理 doc,计算机原理作业.doc

PAGEPAGE 1计算机原理作业单项选择题  1&#xff0e;指令JMP?FAR?PTR?DONE属于     A&#xff0e;段内转移直接寻址   B&#xff0e;段内转移间接寻址   C&#xff0e;段间转移直接寻址   D&#xff0e;段间转移间接寻址2&#xff0e;下列叙述正确的是    …

运行下的命令

oobe/msoobe /a----检查XP是否激活 notepad--------打开记事本 gpedit.msc-----组策略 sndrec32-------录音机 Nslookup-------IP地址侦测器 explorer-------打开资源管理器 logoff---------注销命令 tsshutdn-------60秒倒计时关机命令 lusrmgr.msc----本机用户和组 services.…

SQL2008R2的 遍历所有表更新统计信息 和 索引重建

【2.以下是更新统计信息】 DECLARE UpdateStatisticsTables CURSOR READ_ONLY FORSELECT sst.name,Schema_name(sst.schema_id)FROM sys.tables sstWHERE sst.TYPE UDECLARE name VARCHAR(80),schema VARCHAR(40)OPEN UpdateStatisticsTablesFETCH NEXT FROM UpdateStati…

计算机语言up,TweakBit PCSpeedUp

&#xfeff;TweakBit PCSpeedUp是一款深层次的pc系统优化软件&#xff0c;它可以帮你深度清理电脑系统&#xff0c;扫描系统中的重复、缓存文件并帮你清理这些占用空间的东西&#xff0c;让你的系统解放出来&#xff0c;运行速度更快&#xff0c;更高效。软件介绍&#xff1a;…

mysql五-1:单表查询

一 介绍 本节内容: 查询语法 关键字的执行优先级 简单查询 单条件查询:WHERE 分组查询:GROUP BY HAVING 查询排序:ORDER BY 限制查询的记录数:LIMIT 使用聚合函数查询 使用正则表达式查询 company.employee员工id id int 姓名 emp_na…

ST、SC、FC、LC光纤接头区别

ST、SC、FC、LC光纤接头区别ST、SC、FC光纤接头是早期不同企业开发形成的标准&#xff0c;使用效果一样&#xff0c;各有优缺点。 ST、SC连接器接头常用于一般网络。ST头插入后旋转半周有一卡口固定&#xff0c;缺点是容易折断&#xff1b;SC连接头直接插拔&#xff0c;使用很方…

计算机部分选择怎么操作,计算机基础试题选择题部分

计算机基础试题选择题部分《计算机基础》选择题1、世界上第一台电子计算机研制成功的时间是___________。 A、1936 B、1956 C、1946 D、19752、世界上第一台电子数字式计算机的____________。 A、ENDAC B、ENIAC C、UNIVAC D、EDVAC3、被称为计算机之父的是__________。 A、艾伦…

查看apk包名和Activity的方法

使用adb shell dumpsys window | findstr mCurrentFocus 命令查看当前运行的包名和Activity 包名&#xff1a;com.mymoney Activity:com.mymoney.ui.main.MainActivity 转载于:https://www.cnblogs.com/Bella-fu/p/7516056.html

图片防盗链

using System;using System.Web;/// <summary>/// ImageProtect 的摘要说明/// </summary>public class ImageProtect : IHttpHandler{ public ImageProtect() { // // TODO: 在此处添加构造函数逻辑 // } public void ProcessRe…