zoukankan      html  css  js  c++  java
  • 单元测试笔记,静态方法的测试和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);
           }
    今天老师给指点了一下单测,为了防止自己遗忘,就先记录一下。后续等在研究一下,再补充其他的吧。
     
     
    分享是种美德!
     
     
    点滴积累,每天进步一点点!O(∩_∩)O~
  • 相关阅读:
    Unknown custom element: <el-container1>
    jQuery手机对话框插件
    告别2013,迎接2014
    淘宝开放平台主动通知的实现
    搭建JavaWeb服务器
    深入理解JavaScript执行上下文和执行栈
    为什么要选择学习Java?适合零基础的初学者的文章
    成为一名优秀的Java程序员9+难以置信的公式
    深入理解JavaScript作用域和作用域链
    JavaScript数据类型转换
  • 原文地址:https://www.cnblogs.com/hager/p/5726007.html
Copyright © 2011-2022 走看看