C# 单元测试

304 阅读2分钟

这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战

测试的重要性

假如你需要开发一个生死蒲管理系统,你完成了其中增删姓名、修改阳寿的功能。

开发好功能之后,你交付给了大BOOS,但好景不长。管理员在修改阳寿时,输入了一个不存在生死蒲里的姓名。继而引发了NullReferenceException,管理员还未来得及保存,生死蒲就已经停止响应,管理员一气之下把这件事情告诉了大BOOS,你被扣掉了一bei块的工资😭

src=http___www.kalvin.cn_uploads_images_20200513_20200513162500_42140.jpg&refer=http___www.kalvin.jpg

📢1.1 为什么需要测试

软件开发当中,由于需求或环境的变更、通常会产生许多意料外的情况。传统测试一般通过人工点击页面上的按钮,已确认程序运行效果是否符合预期,但这种操作总是过度的繁琐。且还有漏测与测过了但是没有记载参数的情况。所以在开发大型软件过程中,我们须得做好单元测试这一项工作,以帮助我们减少重复工作,不必没日没夜的debug...从而迎娶白富美走向人生巅峰...

📢1.2 单元测试

使用dotnet CLI 创建 xunit 测试项目

image.png

dotnet new xunit -o PrimeService.Tests
  1. 服务代码:

image.png

  1. 测试代码:

image.png

我们通过UnitTest1的构造函数,获取了ShengSiPu的实例,Shoud_Expect是一个 测试,方法里面有Assert.IsNotEmpty方法,他的含义代表 GetValue 的返回值不能为空。接下来,我们运行一下测试:

image.png

当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重写,再次运行测试的截图

image.png

因为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测试通过