在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;
}
/// <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
在C#中进行单元测试的更多相关文章
- Visual Studio中UnitTesting单元测试模板代码生成
在软件研发过程中,单元测试的重要性直接影响软件质量.经验表明一个尽责的单元测试方法将会在软件开发的某个阶段发现很多的Bug,并且修改它们的成本也很低.在软件开发的后期阶段,Bug的发 ...
- 真正意义上的spring环境中的单元测试方案spring-test与mokito完美结合
真正意义上的spring环境中的单元测试方案spring-test与mokito完美结合 博客分类: java 测试 单元测试SpringCC++C# 一.要解决的问题: spring环境中 ...
- 在Android中进行单元测试遇到的问题
问题1.Cannot connect to VM socket closed 在使用JUnit进行测试的时候,遇到这个问题.网上的解释是:使用Eclipse对Java代码进行调试,无论是远程JVM还 ...
- 在Android Studio中进行单元测试和UI测试
本篇教程翻译自Google I/O 2015中关于测试的codelab,掌握科学上网的同学请点击这里阅读:Unit and UI Testing in Android Studio.能力有限,如有翻译 ...
- Visual Studio 中的单元测试 UNIT TEST
原文:Visual Studio 中的单元测试 UNIT TEST 注:本文系作者原创,可随意转载,但请注明出处.如实在不愿注明可留空,强烈反对更改原创出处.TDD(Test-Driven Devel ...
- TDD中的单元测试
TDD中的单元测试写多少才够? 测试驱动开发(TDD)已经是耳熟能详的名词,既然是测试驱动,那么测试用例代码就要写在开发代码的前面.但是如何写测试用例?写多少测试用例才够?我想大家在实际的操作过程 ...
- 【Unity游戏开发】浅谈Unity游戏开发中的单元测试
一.单元测试的定义与作用 单元测试定义:单元测试在传统软件开发中是非常重要的工具,它是指对软件中的最小可测试单元进行检查和验证,一般情况下就是对代码中的一个函数去进行验证,检查它的正确性.一个单元测试 ...
- SpringMVC,MyBatis项目中兼容Oracle和MySql的解决方案及其项目环境搭建配置、web项目中的单元测试写法、HttpClient调用post请求等案例
要搭建的项目的项目结构如下(使用的框架为:Spring.SpingMVC.MyBatis): 2.pom.xml中的配置如下(注意,本工程分为几个小的子工程,另外两个工程最终是jar包): 其中 ...
- 好代码是管出来的——.Net Core中的单元测试与代码覆盖率
测试对于软件来说,是保证其质量的一个重要过程,而测试又分为很多种,单元测试.集成测试.系统测试.压力测试等等,不同的测试的测试粒度和测试目标也不同,如单元测试关注每一行代码,集成测试关注的是多个模块是 ...
- 在.NET开发中的单元测试工具之(2)——xUnit.Net
在上一篇<在.NET开发中的单元测试工具之(1)——NUnit>中讲述了如何使用NUnit在.NET开发中进行单元测试以及NUnit的一些缺点,今天将讲述如何使用xUnit.Net来进行单 ...
随机推荐
- vue-cli快速搭建项目的几个文件(一)
===========app.vue文件============= <template> <div id="app"> <router ...
- vue+vant实现省市联动(van-area)组件(包含比较全面的全国省市数组数据)
组件库太香了,人家nb,自己写的都是** 效果: 1.安装vant库以及main.js的配置 2.一般结合van-popup组件 </template> <van-popup v-m ...
- HouseParty原创故事全角色关系及主线剧情介绍(最新版)
这是原创故事的主要的角色的主线及支线剧情的介绍及攻略和注意事项等. 这里的图比哔哩哔哩上的图清楚一点,哔哩哔哩同号:宅猫君007 以上是全角色的关系图 最新版本的游戏下载就在我的网站上:https:/ ...
- 如何在Ubuntu 20.04上安装Pyenv 管理多版本Python
目录 ubuntu安装pyenv 管理多版本Python 参考文档: 安装pyenv: pyenv 命令列表 pycharm配置 ubuntu安装pyenv 管理多版本Python 参考文档: htt ...
- 微信小程序使用微信云托管添加自定义域名并转发到pexels.com
背景:我要在小程序上显示pexels.com上的图片,然后我得先把pexels.com的域名添加到小程序的request合法域名中,但是pexels.com是国外的,在国内没有备案所以添加不了.解决方 ...
- 超级简单实用的CSS3动画,增添网页效果
有时候做网页,如果都写成静态的没有动态效果,犹如一张张图片,没有视觉感受,没有达到很好的视觉效果. 其实一些简单的CSS3动画,可以增添网页的动态感,使自己设计的网页更有视觉享受.1.图片有一定角度的 ...
- vue特殊attribute-ref
vue.js中文社区文档:ref 被用来给元素或子组件注册引用信息.引用信息将会注册在父组件的 $refs 对象上.如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素:如果用在子组件上,引 ...
- 教你如何搞定springboot集成kafka
本文分享自华为云社区<手拉手入门springboot+kafka>,作者:QGS. 安装kafka 启动Kafka本地环境需Java 8+以上 Kafka是一种高吞吐量的分布式发布订阅消息 ...
- pageoffice 6 实现数据区域填充(插入文本、图片、word、excel等)
在实际的Word文档开发中,经常需要自动填充数据到Word模板中,以生成动态的Word文档. 例如: 1.我们可以根据数据库表中已保存的个人信息,设计好一个简历模板docx文件,然后通过代码将这些个人 ...
- Java中CAS算法的集中体现:Atomic原子类库,你了解吗?
一.写在开头 在前面的博文中我们学习了volatile关键字,知道了它可以保证有序性和可见性,但无法保障原子性,结局原子性问题推荐使用synchronized.Lock或者AtomicInteger: ...