单元测试笔记,静态方法的测试和Mock

测试三个步骤:
1、接口---》2、造数据---》3、验证结果;
 
静态方法的测试:
  对于静态方法的测试,一般是在其基础上,封装一个接口和实现类,方便后续的Mock模拟。
个人理解,大致原理就是拦截实际接口,然后替换为Mock的接口逻辑,这样就可以过滤掉其他外部的依赖,同样也可以让单测功能更加单纯。比如:
 
public interface ILogHelper
   {
       void LogInfo(string info);
   }
 
   public class SuperLogHelper : ILogHelper
   {
       public void LogInfo(string info)
       {
           LogHelper.LogInfo(info);
       }
   }
在使用类内部,通过接口方式使用:比如
private static ILogHelper _superLogHelper = new SuperLogHelper();
这样,在单元测试时,就可以Mock一些逻辑了,比如:
[TestMethod()]
       public void GetApproveSmsCode_Test_When_GetReturnNull_ReturnNull()
       {
// mock logger
           var mockLogger = new Mock<ILogHelper>();
           mockLogger.Setup(p => p.LogInfo(It.IsAny<string>()));
       // mock httpHelper
           var mock = new Mock<ISuperHttpHelper>();
           mock.Setup(p => p.Get(It.IsAny<string>())).Returns((SmsApproveModel)null);
 
           var sendSmsHelper = new PrivateType(typeof(SendSmsHelper));
           sendSmsHelper.SetStaticFieldOrProperty("superHttpHelper", mock.Object);
           sendSmsHelper.SetStaticFieldOrProperty("_superLogHelper", mockLogger.Object);
 
           var model = sendSmsHelper.InvokeStatic("GetApproveSmsCaptcha", string.Empty, string.Empty, string.Empty,string.Empty, string.Empty);
 
           Assert.AreEqual(null, model);// 验证model为null
           mock.Verify(p => p.Get(It.IsAny<string>()), Times.Once);// 验证httphelper.get方法调用一次
           mockLogger.Verify(p => p.LogInfo(It.IsAny<string>()), Times.Never);// 验证logInfo方法不被调用
       }
对于一些特殊场景,比如我想要知道我请求的方法中的URL是什么。怎么办呢?也可以通过自定义Mock进行自定义输出;比如:
被测试方法代码:
public static SmsApproveModel GetApproveSmsCaptcha(string appid, string consumerId, string ip, string mobile, string guid = "")
        {
            string url;
            if (!CheckUrlIsExist(ApproveSmsCaptchaUrl, out url)) return null;
 
            url = string.Format(url, appid, consumerId, ip, mobile);
 
            if (!string.IsNullOrWhiteSpace(guid))
                url += "&guid=" + guid;
 
            var smsApproveModel = superHttpHelper.Get(url);
 
            if (smsApproveModel != null)
                //LogHelper.LogInfo(smsApproveModel.ToJson());
                _superLogHelper.LogInfo(smsApproveModel.ToJson());
 
            return smsApproveModel;
        }
想要知道url内容,那么可以从HttpHelper.Get方法下手:
/// <summary>
   /// 自定义Mock实现类
   /// </summary>
   public class SuperHttpHelperMock : ISuperHttpHelper
   {
       public string Url { get; set; }
       public SmsApproveModel Get(string url)
       {
           Url = url;
           return null;
       }
   }
测试代码:
[TestMethod()]
       public void GetApproveSmsCode_Test()
       {
           var myMock = new SuperHttpHelperMock(); 
           var sendSmsHelper = new PrivateType(typeof(SendSmsHelper));
           sendSmsHelper.SetStaticFieldOrProperty("superHttpHelper", myMock);
           var model = sendSmsHelper.InvokeStatic("GetApproveSmsCaptcha", "m", "test", "1.1.1.1", "13800138000", "");
 
           Assert.AreEqual("http://www.xxx.com/code/create?_appId=m&consumerId=test&ip=1.1.1.1&mobile=13800138000", myMock.Url);
       }

 

今天老师给指点了一下单测,为了防止自己遗忘,就先记录一下。后续等在研究一下,再补充其他的吧。
 
 
分享是种美德!
 
 
posted @ 2016-08-01 15:27  iMhager  阅读(1935)  评论(0编辑  收藏  举报