这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战
测试的重要性
假如你需要开发一个生死蒲管理系统,你完成了其中增删姓名、修改阳寿的功能。
开发好功能之后,你交付给了大BOOS,但好景不长。管理员在修改阳寿时,输入了一个不存在生死蒲里的姓名。继而引发了NullReferenceException,管理员还未来得及保存,生死蒲就已经停止响应,管理员一气之下把这件事情告诉了大BOOS,你被扣掉了一bei块的工资😭
📢1.1 为什么需要测试
软件开发当中,由于需求或环境的变更、通常会产生许多意料外的情况。传统测试一般通过人工点击页面上的按钮,已确认程序运行效果是否符合预期,但这种操作总是过度的繁琐。且还有漏测与测过了但是没有记载参数的情况。所以在开发大型软件过程中,我们须得做好单元测试这一项工作,以帮助我们减少重复工作,不必没日没夜的debug...从而迎娶白富美走向人生巅峰...
📢1.2 单元测试
使用dotnet CLI 创建 xunit 测试项目
dotnet new xunit -o PrimeService.Tests
- 服务代码:
- 测试代码:
我们通过UnitTest1的构造函数,获取了ShengSiPu的实例,Shoud_Expect是一个 测试,方法里面有Assert.IsNotEmpty方法,他的含义代表 GetValue 的返回值不能为空。接下来,我们运行一下测试:
当Should_Expect测试通过时,前面的图标会着色为绿色
📢1.3 mock [ 模拟测试 ]
有些时候,某个方法需要从数据库来获取一个值。但是数据库里存的值可能不符合我们想输入的值。这个值我们又不想每次测试的时候都要去添加数据,所以运行不到我们想要运行的分支。因此,测试无法进行下去,此时,我们就需要一个模拟框架(moq),他能自动将这个方法的返回值简单粗暴的改为我们的预期值
如下:
public class ShengSiPu
{
private Dictionary<string, string> UsersCatalog = new()
{
{ "王阳明", "嘉靖八年" },
{ "庄周", "周赧王十七年" }
};
public string GetValue(string userId)
{
if (IsClosingTime())
{
return null;
}
return UsersCatalog[userId];
}
public virtual bool IsClosingTime()
{
TimeSpan closingTime = new TimeSpan(18, 30, 30);
//22:30 下班拉!不给查
return DateTime.Now.TimeOfDay >= closingTime;
}
}
我将IsClosingTime设置为了virutal以便moq重写,再次运行测试的截图
因为GetValue返回了NUll值,测试方法现标志为不通过了,这里假设IsClosingTime方法是从数据库中获取的值。我们来使用moq改写一下(注意先安装Moq包):
[Fact]
public void Should_Expect()
{
var mock = new Mock<ShengSiPu>();
mock.Setup(spu => spu.IsClosingTime()).Returns(false);
Assert.NotNull(mock.Object.GetValue("王阳明"));
}
更改IsClosingTime的返回值后,Should_Expect测试通过