在C#开发中,单元测试是验证单个代码单元功能正确性的重要手段,xUnit是.NET生态中常用的单元测试框架,支持灵活的测试用例编写和丰富的断言能力,适合各类C#项目的测试需求。

xUnit环境准备
首先需要在C#项目中引入xUnit相关依赖,以.NET 6及以上版本的项目为例,创建测试项目的步骤如下:
- 在解决方案中新建一个xUnit测试项目,选择xUnit Test Project模板
- 如果是已有项目,也可以通过NuGet安装xUnit相关包,需要安装的核心包包括xunit和xunit.runner.visualstudio
安装完成后,项目会自动引用xUnit的核心库,无需额外复杂配置即可开始编写测试用例。
编写基础测试用例
xUnit中测试用例通过特性标记实现,不需要继承特定基类,方法上添加[Fact]特性即可标记为无参数的测试用例,添加[Theory]特性可以标记带参数的测试用例。
假设我们有一个简单的计算器类,代码如下:
// 计算器类,提供基础运算方法
public class Calculator
{
// 两个整数相加的方法
public int Add(int a, int b)
{
return a + b;
}
// 两个整数相减的方法
public int Subtract(int a, int b)
{
return a - b;
}
}
对应的xUnit测试类代码如下:
using Xunit;
// 测试类,通常和被测试类同名加Tests后缀
public class CalculatorTests
{
// 无参数测试用例,使用Fact特性标记
[Fact]
public void Add_TwoNumbers_ReturnsCorrectSum()
{
// 准备测试数据
var calculator = new Calculator();
int a = 3;
int b = 5;
int expected = 8;
// 执行被测试方法
int actual = calculator.Add(a, b);
// 断言结果是否符合预期
Assert.Equal(expected, actual);
}
// 带参数的测试用例,使用Theory特性标记,配合InlineData提供测试数据
[Theory]
[InlineData(10, 2, 8)]
[InlineData(5, 3, 2)]
[InlineData(0, 0, 0)]
public void Subtract_TwoNumbers_ReturnsCorrectResult(int a, int b, int expected)
{
var calculator = new Calculator();
int actual = calculator.Subtract(a, b);
Assert.Equal(expected, actual);
}
}
常用断言方法
xUnit的Assert类提供了丰富的断言方法,用于验证测试结果是否符合预期,常用的断言方法如下:
| 断言方法 | 作用说明 |
|---|---|
| Assert.Equal(expected, actual) | 验证两个值是否相等 |
| Assert.NotEqual(expected, actual) | 验证两个值是否不相等 |
| Assert.True(condition) | 验证条件是否为真 |
| Assert.False(condition) | 验证条件是否为假 |
| Assert.Null(obj) | 验证对象是否为null |
| Assert.NotNull(obj) | 验证对象是否不为null |
| Assert.Throws<TException>(func) | 验证执行方法时是否抛出指定类型的异常 |
例如测试一个会抛出异常的方法,代码示例如下:
using Xunit;
public class ExceptionTests
{
// 被测试方法,除数为0时抛出DivideByZeroException
public int Divide(int a, int b)
{
if (b == 0)
{
throw new DivideByZeroException();
}
return a / b;
}
[Fact]
public void Divide_ByZero_ThrowsDivideByZeroException()
{
var testObj = new ExceptionTests();
// 验证调用Divide方法传入0作为除数时,是否抛出DivideByZeroException异常
Assert.Throws<DivideByZeroException>(() => testObj.Divide(10, 0));
}
}
执行单元测试
编写完成测试用例后,可以通过多种方式执行测试:
- 在Visual Studio中,打开测试资源管理器,右键选择要运行的测试项目或单个测试用例,点击运行即可执行测试
- 如果使用命令行,可以在测试项目目录下执行
dotnet test命令,会自动发现并执行所有测试用例,输出测试结果
测试执行完成后,会显示通过和失败的测试用例数量,点击失败的用例可以查看具体的失败原因和堆栈信息,方便定位代码问题。
测试生命周期管理
xUnit中每个测试用例都是独立的,测试类的构造函数会在每个测试用例执行前调用,可以用来初始化测试所需的资源,实现类似其他测试框架中Setup方法的功能。
示例代码如下:
using Xunit;
public class LifecycleTests
{
private readonly Calculator _calculator;
// 构造函数,每个测试用例执行前都会调用,初始化测试对象
public LifecycleTests()
{
_calculator = new Calculator();
}
[Fact]
public void Add_Test1()
{
// 这里可以直接使用初始化好的_calculator对象
var result = _calculator.Add(1, 2);
Assert.Equal(3, result);
}
[Fact]
public void Add_Test2()
{
var result = _calculator.Add(4, 5);
Assert.Equal(9, result);
}
}
如果需要清理测试资源,可以在测试类中实现IDisposable接口,在Dispose方法中编写清理逻辑,该方法会在每个测试用例执行完成后调用。