使用Microsoft Fakes进行单元测试(1)

一:什么是单元测试

单元测试是对软件进行准确性验证的步骤。单元测试并不进行整个软件功能的测试,仅仅是对于最小工作单元的测试。一般最小工作单元就是指方法/函数等。 这里并不打算对单元测试的概念及基础进行更多的介绍,需要了解更多的自行google。

二:UnitTestFramework

UnitTestFramework是微软开发的一套单元测试框架。类似的三方框架有NUnit等。UnitTestFramework为单元测试提供断言,自动化测试,管理界面等功能。与VisualStudio无缝集成。

三:Microsoft Fakes

Microsoft Fakes是UnitTestFramework下的高级组件。Microsoft Fakes可以帮我们隔离测试的代码。我们的代码/方法很多时候并不是完全独立的。一个方法会受到传入的参数的影响,一个方法也可能去调用另外一个方法才能正确的执行。所以当我们想要对一个方法进行单元测试的时候,如果有其他因素影响,那么我们很难确定这个方法失败错误的真实原因。所以我们进行单元测试的时候就要想办法消除这些影响。这个时候我们可以用Microsoft Fakes。Microsoft Fakes可以用来模拟接口,静态方法等,通过Microsoft Fakes模拟的方法,具有稳定的,可以预期的返回值,这个时候我们就可以认为消除了外部模块对单元测试的影响。 注意:Microsoft Fakes并不是所有版本的VisualStudio都支持,通常只有高级版本才包含。比如VisualStudio2015只有Enterprice版本才支持。 Microsoft Fakes主要有2大功能: stub: 一个stub可以用来替换一个实现了某个接口的class。简单的说stub可以用来快速的实现一个接口,用来测试。使用stub来测试,你的程序必须是面向接口设计的。 shim: 一个shim可以用来替换一个你已经编译完成的库中的某个方法,当你的测试运行的时候,调用的是shim模拟的方法。shim可以用来模拟那些你无法修改的程序集的方法,比如.NET内置类库。

四:示例

1.使用Stub来模拟接口 使用VisualStudio新建一个项目叫做MSFakeSample:

我们想象这样一个业务需求。我们需要把所有学生的名称组合成一个用逗号分隔的字符串。所有的学生信息存放在数据库里。 IStudentsRepository 这个接口描述的是Students仓储类需要实现的功能。

StudentsService 这类是用来实现Students的业务逻辑。

按照正常的开发逻辑,我们这个时候还需要去实现IStudentsRepository这个接口,也许是封装EF,也许是封装Dapper等等,然后才能去测试ConnectNames这个方法。但是尽管用EF等去实现了IStudentsRepository接口,我们的测试方法严重依赖了仓储层,数据库。也许为了测试我们还需要配置数据库连接,添加模拟数据到数据库。任何IStudentsRepository实现类的变化,或者数据库的变化,都可能影响到单元测试的结果。如果我们可以隔离这些变化那么我们的单元测试将变得非常完美。 有了Microsoft Fakes我们可以模拟一个实现了IStudentsRepository的类,来完全的隔离IStudentsRepository实现类的变化,或者数据库的变化。 创建单元测试类 在ConnectNames方法上右击,点击创建单元测试

在弹出的创建单元测试对话框上点击确定,程序就会自动创建一个以当前项目名称+Tests的项目,并且为你生成一个测试类StudentsServiceTests。

添加Fakes程序集 新增的Tests项目会自动引用MSFakeSample项目,在引用下右击MSFakeSample,点击添加Fakes程序集

点击添加Fakes程序集后VS会自动生成一个MSFakeSample.fakes的库并且引用。

使用stub来模拟接口 有了上面的这些操作,我们就可以开始真正的使用Fakes的Stub来模拟接口了。

我们直接new了3个StubIStudentsRepository类,并且用Lambda表达式直接定义了3个方法,分别返回null,空List,跟一个正常的List来描述3种情况。然后用Assert去断言跟预期的结果是否一致。 运行单元测试 Ctrl+T+R直接运行,会弹出单元测试运行窗口

可以看到ConnectNamesTest Passed,测试通过了。 通过使用Fakes的Stub功能,我们可以轻而易举的模拟接口。利用Lambda表达式来直接控制方法的返回值,使其稳定不变,从而为测试方法隔离接口。 不管你真正的接口如何实现,我测试的方法永远不会受到影响。 2.使用Shim模拟静态方法 太晚了,下回分解吧。晚安~

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏北京马哥教育

DNS从入门到管理(一)

DNS概述 DNS(Domain Name System,域名系统),域名和IP地址相互映射的一个分布式数据库,通过主机名,最终得到该主机名对应的IP地址的过程...

4736
来自专栏张善友的专栏

在 ASP.NET 2.0 中,Global.asax 文件没有后置代码,如何将Globa.asax中的页面移到代码文件中

学海无涯在asp.net页面上得到Castle容器的实例 中问如何解决这个问题,可以如下设定来完成这个功能 <%@ Application Inherits="...

18710
来自专栏python爬虫日记

python下wxpython程序国际化的实践(中文英文切换)

i18n是 Internationalization 这个英文的简写,因为Internationalization这个单词去掉头尾的i和n刚好还剩下18个字符,...

902
来自专栏软件工程师成长笔记

SSM框架——干净详细的整合学习教程(Spring+SpringMVC+MyBatis)

熟悉MVC的同学都知道,MVC即model(模型)、view(视图)、controller(控制),用一种业务逻辑,数据,界面显示分离的方式使得开发更加的便捷高...

1822
来自专栏Python

浏览器User-Agent大全

HttpHeader之User-Agent UserAgent中文名为用户代理,是Http协议中的一部分,属于头域的组成部分,UserAgent也简称UA。它是...

972
来自专栏蓝天

LINUX系统性能调谐

邓延军 (deng.yanjun@163.com), 硕士研究生, 西安电子科技大学软件工程研究所

792
来自专栏杂烩

spring安全框架Security(一) 转

    现在很多企业和开发团队都使用了SSH2(Struts 2 +Spring 2.5 +Hibernate)框架来进行开发,  我们或许已经习惯了强大的Sp...

643
来自专栏Seebug漏洞平台

Python 安全 - 从 SSRF 到命令执行惨案

前两天遇到的一个问题,起源是在某个数据包里看到 url= 这个关键字,当时第一想到会不会有 SSRF 漏洞。 以前乌云上有很多从 SSRF 打到内网并执行命...

3029
来自专栏北京马哥教育

SSL/TLS 原理详解

SSL/TLS作为一种互联网安全加密技术,原理较为复杂,枯燥而无味,我也是试图理解之后重新整理,尽量做到层次清晰。正文开始。 1. SSL/TLS概览 1.1...

3365
来自专栏技术博文

redis配置详解

##redis配置详解 # Redis configuration file example. # # Note that in order to read ...

2615

扫码关注云+社区