• 在C#中进行单元测试


    单元测试

    前言

    时隔多个月,终于抽空学习了点新知识,那么这次来记录一下C#怎么进行单元测试,单元测试是做什么的。

    我相信大部分刚毕业的都很疑惑单元测试是干什么的?在小厂实习了6个月后,我发现每天除了写CRUD就是写CRUD,几乎用不到单元测试。写完一个功能直接上手去测,当然这只是我个人感受,仅供参考。

    然后当我还在抱怨测试好烦的时候,大佬跟我说为什么不用单元测试和集成测试,我这也是有苦说不出。要知道光学会理论知识,没有实践作为基础,都是扯淡,入职这么久还真没用过单元测试,吓得我赶紧去找资料学习。

    那么也是通过观看B站某位Up主的视频,然后有点想法写下这篇文章,虽然up主的主题是探究接口的作用和意义,但是视频中也讲解了怎么进行单元测试,所以对于接口理解不够的可以去本文底部观看视频学习。

    那么本篇文章就简单的讲解下C#中如何做单元测试,博主也是处于学习阶段,有不对的地方欢迎指出改正。

    单元测试简述

    单元测试(Unit Testing)是软件开发中的一种测试方法,用于验证代码中的最小可测试单元(通常是方法或函数)是否按照预期进行工作。这些单元通常是独立于其他代码部分进行测试的,以确保其正确性和可靠性。

    单元测试的主要作用:

    • 确保每个单元能正确执行预期功能
    • 能够尽快找到Bug的具体位置

    开始测试

    本文以当前时间去返回早上好、中午好、晚上好来讲解单元测试。

    通过传入不同的时间(边界值)来确保代码能够正确处理各种情况以及是否达到了预期的功能。

    预期结果为:

    • 早上好...
    • 中午好...
    • 晚上好..

    项目搭建

    主程序

    首先需要创建一个控制台项目,起名为UnitTesting

    并安装Microsoft.Extensions.DependencyInjection包,管理IOC容器。

    创建ITimeProvider接口,并创建SystemTimeProvider类去实现这个接口

    public interface ITimeProvider
    {
        int GetHour();
    }
    //返回当前时间
    public class SystemTimeProvider: ITimeProvider
    {
        public int GetHour()
        {
            return DateTime.Now.Hour;
        }
    }
    

    创建GreetingService

    public class GreetingService
    {
        private readonly ITimeProvider _timeProvider;
    
        public GreetingService(ITimeProvider timeProvider)
        {
            _timeProvider = timeProvider;
        }
        /// 
        /// 通过当前时间来打返回问候语
        /// 
        /// 
        /// 
        public string Greet(string name)
        {
            var hour = _timeProvider.GetHour();
            return hour switch
            {
                < 12 => $"Good Morning,{name}",
                < 18 => $"Good Afternoon,{name}",
                _ => $"Good Evening,{name}"
            };
        }
    }
    

    Program.cs使用IOC容器注入服务并调用Greet方法

    using Microsoft.Extensions.DependencyInjection;
    using UnitTesting.Services;
    
    var container = new ServiceCollection();
    container.AddSingleton();
    container.AddTransient();
    var services = container.BuildServiceProvider();
    
    var greetingService = services.GetRequiredService();
    var greeting = greetingService.Greet("吗喽");
    Console.WriteLine(greeting);
    

    测试程序

    xUnit模版创建单元测试,名为UnitTesting.Test,并添加UnitTesting项目引用,还需安装Moq包:

    Moq包(全称Mocking Objects in C#,简称Moq)是一个流行的模拟框架,其主要作用在于模拟和验证对象的行为,以支持更加可靠和可重复的测试,简单来讲就是模拟创建对象。

    回到GreetingService类,这里使用Rider提供的快捷方式创建测试类,当然也可以手动创建。如图:

    image

    测试流程:

    • Arrange:准备阶段,创建ITimeProvider的模拟对象provider,并指定时间参数且调用GetHour()方法,使用这个模拟对象创建GreetingService实例。
    • Act:执行阶段,调用GreetingServiceGreet方法
    • Assert:断言阶段,验证返回的消息是否与预期的结果相同。
    using JetBrains.Annotations;
    using Moq;
    using UnitTesting.Services;
    
    namespace UnitTesting.Tes.Services;
    
    [TestSubject(typeof(GreetingService))]
    public class GreetingServiceTests
    {
        [Fact]
        public void GreetReturnsMorningMessage()
        {
            // Arrange
            var provider = new Mock();
            provider.Setup(x => x.GetHour()).Returns(10);
            var service = new GreetingService(provider.Object);
    
            // Act
            var message = service.Greet("吗喽");
    
            // Assert
            Assert.Equal("Good Morning,吗喽", message);
        }
        [Fact]
        public void GreetReturnsAfternoonMessage()
        {
            // Arrange
            var provider = new Mock();
            provider.Setup(x => x.GetHour()).Returns(15);
            var service = new GreetingService(provider.Object);
    
            // Act
            var message = service.Greet("吗喽");
    
            // Assert
            Assert.Equal("Good Afternoon,吗喽", message);
        }
        [Fact]
        public void GreetReturnsEveningMessage()
        {
            // Arrange
            var provider = new Mock();
            provider.Setup(x => x.GetHour()).Returns(20);
            var service = new GreetingService(provider.Object);
    
            // Act
            var message = service.Greet("吗喽");
    
            // Assert
            Assert.Equal("Good Evening,吗喽", message);
        }
    }
    

    效果截图

    主程序没什么好讲的,通过当前时间返回问候语。

    image

    测试程序通过3个测试方法测试了3种情况,早上好、中午好、晚上好,并全部测试通过。

    image

    总结

    本文讲解了如何创建单元测试,并且通过单元测试来测试Greet方法,在传入不同的时间参数的情况下,判断是否满足3种情况。

    本文提到了IOC容器、依赖注入、Moq、xUnit等知识点。

    参考链接


    __EOF__

  • 本文作者: 妙妙屋(zy)
  • 本文链接: https://www.cnblogs.com/zyplj/p/18270869
  • 关于博主: 评论和私信会在第一时间回复。或者直接私信我。
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 相关阅读:
    Token和Session有什么区别,面试官满意的答案
    十一、组合API(3)
    vue后台实现点击图片放大
    Tomcat 启动闪退问题解决集(八大类详细)
    Windows系统连接华为eNSP模拟器配置FTP实验
    都 2022 年了,你真的会用 Python 的 pip 吗?
    分布式实时仿真系统-反射内存的应用
    Hadoop 高可用配置及其集群搭建
    方法(构造方法)与方法重载
    太空射击第17课: Game Over (結束)
  • 原文地址:https://www.cnblogs.com/ZYPLJ/p/18270869