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以及第三方类库等。

原文地址:http://www.cnblogs.com/Dongmy/p/16857465.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性