在c#项目开发中,单元测试是针对代码中最小可测试单元进行验证的手段,能够有效提前发现代码逻辑缺陷,降低后续维护成本。合理的单元测试可以让代码重构更有底气,也能提升团队协作时的代码交付质量。

c#单元测试常用框架选择
目前c#生态中主流的单元测试框架有三个,开发者可以根据项目需求选择:
- xUnit:目前微软官方推荐的主流测试框架,支持.NET Core和.NET Framework,设计更现代,没有依赖特定的测试运行器,生态完善。
- NUnit:老牌测试框架,兼容性好,支持多种测试特性,很多 legacy 项目仍在使用。
- MSTest:微软自带的测试框架,和Visual Studio集成度最高,无需额外安装依赖,适合快速上手。
基于xUnit搭建单元测试环境
以.NET 6项目为例,演示如何搭建xUnit测试环境:
1. 创建待测试的业务项目
首先创建一个类库项目,包含一个简单的计算器类作为待测试对象:
// 计算器业务类
public class Calculator
{
// 加法方法
public int Add(int a, int b)
{
return a + b;
}
// 除法方法,除数为0时抛出异常
public int Divide(int a, int b)
{
if (b == 0)
{
throw new ArgumentException("除数不能为0");
}
return a / b;
}
}
2. 创建xUnit测试项目
在解决方案下新建一个xUnit测试项目,然后通过NuGet安装以下两个包:
- xunit
- xunit.runner.visualstudio
安装完成后,测试项目会自动引用业务项目,无需手动添加引用。
编写单元测试用例
xUnit中测试用例通过[Fact]特性标记,不需要测试类继承特定基类,测试方法也没有返回值要求。
基础测试用例编写
针对Calculator类的Add方法编写测试用例:
using Xunit;
// 引入业务类命名空间
using CalculatorDemo;
namespace CalculatorTest
{
public class CalculatorTests
{
// 标记这是一个单元测试方法
[Fact]
public void Add_TwoPositiveNumbers_ReturnsCorrectSum()
{
// 准备阶段:初始化测试对象
var calculator = new Calculator();
// 执行阶段:调用待测试方法
int result = calculator.Add(3, 5);
// 断言阶段:验证结果是否符合预期
Assert.Equal(8, result);
}
[Fact]
public void Add_NegativeAndPositiveNumber_ReturnsCorrectSum()
{
var calculator = new Calculator();
int result = calculator.Add(-2, 5);
Assert.Equal(3, result);
}
}
}
异常测试用例编写
针对Divide方法除数为0的场景,验证是否会抛出预期异常:
using Xunit;
using CalculatorDemo;
namespace CalculatorTest
{
public class CalculatorTests
{
// 其他测试方法省略
[Fact]
public void Divide_DivisorIsZero_ThrowsArgumentException()
{
var calculator = new Calculator();
// 断言调用Divide(10,0)时会抛出ArgumentException异常
Assert.Throws<ArgumentException>(() => calculator.Divide(10, 0));
}
}
}
参数化测试用例
如果同一个测试方法需要验证多组输入数据,可以使用[Theory]配合[InlineData]实现参数化测试:
using Xunit;
using CalculatorDemo;
namespace CalculatorTest
{
public class CalculatorTests
{
// Theory标记参数化测试,InlineData提供多组测试数据
[Theory]
[InlineData(1, 2, 3)]
[InlineData(-1, 1, 0)]
[InlineData(0, 0, 0)]
[InlineData(100, 200, 300)]
public void Add_MultipleInput_ReturnsCorrectSum(int a, int b, int expected)
{
var calculator = new Calculator();
int result = calculator.Add(a, b);
Assert.Equal(expected, result);
}
}
}
执行单元测试
在Visual Studio中,可以通过测试资源管理器执行所有测试用例:
- 打开菜单栏的测试选项,选择测试资源管理器。
- 点击运行所有测试,即可看到所有测试用例的执行结果,包括通过、失败、跳过的用例数量。
- 如果测试用例失败,点击失败的用例可以查看详细的错误信息,包括预期值和实际值的差异。
也可以通过命令行执行测试,在项目目录下运行以下命令:
dotnet test
单元测试最佳实践
- 测试用例命名遵循
方法名_测试场景_预期结果的格式,可读性更高。 - 单个测试用例只验证一个逻辑点,不要在一个测试中验证多个不相关的逻辑。
- 测试代码和生产代码一样需要维护,避免测试代码出现冗余逻辑。
- 优先测试核心业务逻辑,不需要对自动生成的代码或者简单的getter/setter编写测试。
- 使用模拟框架(如Moq)隔离外部依赖,比如数据库、接口调用等,保证单元测试的独立性。
单元测试不是越多越好,而是要在覆盖核心逻辑的前提下保持测试代码的简洁性,过高的测试覆盖率反而会提升维护成本。