单元测试笔记,静态方法的测试和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~