☰分类导航

软件工程/测试与调试
课程进度 82% · 第9/10章第9/10章 · 标签 1/6
— 1 —

xUnit单元测试

原xUnit、Moq和WebApplicationFactory示例依赖测试项目、包引用与可访问的应用入口;仅验证Contains(“Tom”)不足以证明API契约。参考Mock例已补充实际调用和结果断言,避免空测试造成虚假通过。

xUnit是.NET生态中最流行的单元测试框架,与 MSTest 和 NUnit 相比更加轻量和现代化。

Arrange建立已知状态,Act执行业务动作,Assert检查结果与关键副作用。除法用例还应覆盖除数为零和整数截断,标题用例覆盖空白与边界长度。空测试或只验证框架能相加会制造虚假通过,必须证明规则被破坏时测试确实失败。


```csharp
public class Calculator {
    public int Add(int a, int b) => a + b;
    public int Divide(int a, int b) {
        if (b == 0) throw new DivideByZeroException();
        return a / b;
    }
}

// xUnit 测试
public class CalculatorTests {
    [Fact]
    public void Add_ReturnsSum() {
        var calc = new Calculator();
        var result = calc.Add(2, 3);
        Assert.Equal(5, result);
    }

    [Theory]
    [InlineData(10, 2, 5)]
    [InlineData(9, 3, 3)]
    public void Divide_ReturnsQuotient(int a, int b, int expected) {
        var calc = new Calculator();
        var result = calc.Divide(a, b);
        Assert.Equal(expected, result);
    }
}
```
csharp
1
public class Calculator {
2
public int Add(int a, int b) => a + b;
3
public int Divide(int a, int b) {
4
if (b == 0) throw new DivideByZeroException();
5
return a / b;
6
}
7
}
8
 
9
// xUnit 测试
10
public class CalculatorTests {
11
[Fact]
12
public void Add_ReturnsSum() {
13
var calc = new Calculator();
14
var result = calc.Add(2, 3);
15
Assert.Equal(5, result);
16
}
17
 
18
[Theory]
19
[InlineData(10, 2, 5)]
20
[InlineData(9, 3, 3)]
21
public void Divide_ReturnsQuotient(int a, int b, int expected) {
22
var calc = new Calculator();
23
var result = calc.Divide(a, b);
24
Assert.Equal(expected, result);
25
}
26
}

📖[Fact] 表示一个测试方法,[Theory] 结合 [InlineData] 实现参数化测试

— 2 —

集成测试

集成测试验证多个组件协同工作,WebApplicationFactory 可以模拟完整的HTTP请求。

集成测试需要真实注册路由与服务,并明确替换了哪些外部依赖。成功状态码不代表响应归属正确,检查结构、数量和持久化结果;每例使用独立状态,避免依赖执行顺序。假认证有助测业务,但还需单独验证真实令牌配置。


```csharp
public class ApiTests
    : IClassFixture<WebApplicationFactory<Program>> {

    private readonly WebApplicationFactory<Program> _factory;

    public ApiTests(WebApplicationFactory<Program> factory) {
        _factory = factory;
    }

    [Fact]
    public async Task GetUsers_ReturnsSuccess() {
        var client = _factory.CreateClient();
        var response = await client.GetAsync("/api/users");
        response.EnsureSuccessStatusCode();

        var json = await response.Content
            .ReadAsStringAsync();
        Assert.Contains("Tom", json);
    }
}
```
csharp
1
public class ApiTests
2
: IClassFixture<WebApplicationFactory<Program>> {
3
 
4
private readonly WebApplicationFactory<Program> _factory;
5
 
6
public ApiTests(WebApplicationFactory<Program> factory) {
7
_factory = factory;
8
}
9
 
10
[Fact]
11
public async Task GetUsers_ReturnsSuccess() {
12
var client = _factory.CreateClient();
13
var response = await client.GetAsync("/api/users");
14
response.EnsureSuccessStatusCode();
15
 
16
var json = await response.Content
17
.ReadAsStringAsync();
18
Assert.Contains("Tom", json);
19
}
20
}
xUnitNUnit集成测试MockTDD覆盖率