单元测试
前言
时隔多个月,终于抽空学习了点新知识,那么这次来记录一下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;
}
/// <summary>
/// 通过当前时间来打返回问候语
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
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<ITimeProvider,SystemTimeProvider>();
container.AddTransient<GreetingService>();
var services = container.BuildServiceProvider();
var greetingService = services.GetRequiredService<GreetingService>();
var greeting = greetingService.Greet("吗喽");
Console.WriteLine(greeting);
测试程序
用xUnit
模版创建单元测试,名为UnitTesting.Test
,并添加UnitTesting
项目引用,还需安装Moq
包:
Moq包(全称Mocking Objects in C#,简称Moq)是一个流行的模拟框架,其主要作用在于模拟和验证对象的行为,以支持更加可靠和可重复的测试,简单来讲就是模拟创建对象。
回到GreetingService
类,这里使用Rider提供的快捷方式创建测试类,当然也可以手动创建。如图:
测试流程:
- Arrange:准备阶段,创建
ITimeProvider
的模拟对象provider
,并指定时间参数且调用GetHour()
方法,使用这个模拟对象创建GreetingService
实例。 - Act:执行阶段,调用
GreetingService
的Greet
方法 - 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<ITimeProvider>();
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<ITimeProvider>();
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<ITimeProvider>();
provider.Setup(x => x.GetHour()).Returns(20);
var service = new GreetingService(provider.Object);
// Act
var message = service.Greet("吗喽");
// Assert
Assert.Equal("Good Evening,吗喽", message);
}
}
效果截图
主程序没什么好讲的,通过当前时间返回问候语。
测试程序通过3个测试方法测试了3种情况,早上好、中午好、晚上好,并全部测试通过。
总结
本文讲解了如何创建单元测试,并且通过单元测试来测试Greet方法,在传入不同的时间参数的情况下,判断是否满足3种情况。
本文提到了IOC容器、依赖注入、Moq、xUnit等知识点。
参考链接
- 【从单元测试出发探讨接口的作用及意义】 https://www.bilibili.com/video/BV1Ut421V7Sz/?share_source=copy_web&vd_source=fce337a51d11a67781404c67ec0b5084
- Asp-Net-Core学习笔记:单元测试和集成测试 – 程序设计实验室 – 博客园 (cnblogs.com) https://www.cnblogs.com/deali/p/17559685.html
1.本站内容仅供参考,不作为任何法律依据。用户在使用本站内容时,应自行判断其真实性、准确性和完整性,并承担相应风险。
2.本站部分内容来源于互联网,仅用于交流学习研究知识,若侵犯了您的合法权益,请及时邮件或站内私信与本站联系,我们将尽快予以处理。
3.本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
4.根据《计算机软件保护条例》第十七条规定“为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。”您需知晓本站所有内容资源均来源于网络,仅供用户交流学习与研究使用,版权归属原版权方所有,版权争议与本站无关,用户本人下载后不能用作商业或非法用途,需在24个小时之内从您的电脑中彻底删除上述内容,否则后果均由用户承担责任;如果您访问和下载此文件,表示您同意只将此文件用于参考、学习而非其他用途,否则一切后果请您自行承担,如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
5.本站是非经营性个人站点,所有软件信息均来自网络,所有资源仅供学习参考研究目的,并不贩卖软件,不存在任何商业目的及用途
暂无评论内容