VS2012 Unit Test——Microsoft Fakes入门
http://www.javashuo.com/article/p-bxxifltn-hb.html
依我我的理解单元测试就是对程序的小单元进行测试,一个测试不该包含两个或更多单元,整体而言大多都是对方法、属性的编码正确性进行验证。可是每每一个方法又会调用其余的方法或属性,我这里暂称之为外部依赖,于是外部依赖会影响程序单元的测试结果,要避免这样的状况就不得不使用一些外部依赖的模拟进行隔离(Isolate),本文就是使用了Microsoft Fakes,固然还有其余更为流行的框架能够选择使用(Moq、Rhino Mocks、Type Mock)
Fakes有两种形式:stub 和 shim。具体的介绍我就不啰嗦,由于我英文很差可能会表达错误误导新人。编码
个人Demo也是看了MSDN后以我的理解后进行简单的编写,若是MSDN看懂了也就不用看如下内容了,期待和我同样正在使用VS2012 MSTest进行单元测试的一块儿交流进步。url
1、shim
如下将模拟DateTime的Now属性,假设我如今须要在活动服务类ActivityService添加一个方法验证某个线下活动是否过时。
1. 打开VS2012,建立单元测试项目FakesTesting,我这是测试先行。重命名项目自动生成的类UnitTest1为ActivityServiceTest,将TestMethod1改成IsExpireTest(是否过时).
2. 添加代码“ActivityService service = new ActivityService();”并使用VS快捷功能为咱们建立ActivityService 类
3. 添加Fakes,因为DateTime位于System程序集,于是将添加System的Fake程序集(右键System程序集), 而后在测试类“using System.Fakes;”
4. 编写测试代码以下
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Fakes;
using Microsoft.QualityTools.Testing.Fakes;
namespace FakesTesting.Test
{
[TestClass]
public class ActivityServiceTest
{
[TestMethod]
public void IsExpireTest()
{
ActivityService service = new ActivityService();
bool actual = service.IsExpire();
Assert.IsFalse(actual);
using (ShimsContext.Create())
{
ShimDateTime.NowGet = () => new DateTime(2014, 5, 5);
actual = service.IsExpire();
Assert.IsFalse(actual);
}
}
}
}
5. 而后编写ActivityService类
public class ActivityService
{
public DateTime BeginTime { get; set; }
public ActivityService()
{
this.BeginTime = new DateTime(2014, 3, 3); //仅做演示,无心义
}
public bool IsExpire()
{
return BeginTime >= DateTime.Now;
}
}
6. 运行测试经过。而后就能够把实际业务类移动到相应VS项目中,并调整命名空间。
2、Stub
如今假设ActivityService类有一个方法获取是否还能报名,可是它依赖于仓储IActivityRepository(只有遵循依赖反转与接口隔离原则的代码才好使用Stub填充外部依赖)提供的RegisterNumber方法。
1. IActivityRepository接口(新建IRepositories项目并添加该接口)
public interface IActivityRepository
{
/// <summary>
/// 已报名人数
/// </summary>
int RegisterNumber();
}
2. 而咱们的单元测试如今不能依赖具体(实际环境中的Repository可能对测试带来影响),这时候就能使用Stub来填充该接口了,添加IRepositories引用,而后与上一个Demo同样的添加IRepositories的Fakes程序集。
3. 在测试类中添加Using代码
using IRepositories;
using IRepositories.Fakes;
4. 编写测试代码
[TestMethod]
public void CanRegisterTest()
{
StubIActivityRepository repository = new StubIActivityRepository();
ActivityService service = new ActivityService(repository);
//若是已报名人数小于最多可报名数量则不能再报名,断言CanRegister方法应为True
repository.RegisterNumber = ()=> 20;
bool actual = service.CanRegister();
Assert.IsTrue(actual);
//若是已报名人数大于等于最多可报名数量则不能再报名,断言CanRegister方法应为False
repository.RegisterNumber = () => 50;
actual = service.CanRegister();
Assert.IsFalse(actual);
}
5. ActivityService代码:
public class ActivityService
{
public DateTime BeginTime { get; set; }
/// <summary>
/// 最多可报名数量
/// </summary>
private int maxCount = 50;
private IActivityRepository repository;
public ActivityService()
{
this.BeginTime = new DateTime(2014, 3, 3); //仅做演示,无心义
}
public ActivityService(IActivityRepository repository)
{
// TODO: Complete member initialization
this.repository = repository;
}
public bool IsExpire()
{
return BeginTime >= DateTime.Now;
}
public bool CanRegister()
{
return repository.RegisterNumber() < this.maxCount;
}
}
总结
stub用于咱们可控的代码,shim用于不可控的,例如.NET Framework以及第三方类库等。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了