Skip to content

测试简介 ​

更新: 2026-10-16 15:20:09   字数: 0 字   时长: 0 分钟

Aspire 支持对分布式应用进行自动化测试,入口是 Aspire.Hosting.Testing NuGet 包。它提供 DistributedApplicationTestingBuilder 类,用于为应用创建测试宿主:在后台线程中启动 AppHost 项目并管理其生命周期,让您能够控制和操作应用及其资源。

默认情况下,测试构建器会关闭仪表板并随机化被代理资源的端口,从而允许同一应用的多个实例并发运行。测试完成后,释放应用或测试构建器即可清理资源。

理解 Aspire 测试 ​

Aspire 的测试能力是为闭箱(closed-box)集成测试设计的——针对整个分布式应用。与单元测试或开箱集成测试(通常只测单个组件)不同,Aspire 测试会把完整解决方案(AppHost 及其所有资源)作为独立进程启动,尽量贴近真实场景。

测试流程:

  1. 测试项目启动 AppHost。
  2. AppHost 进程启动。
  3. AppHost 运行数据库、API 与前端应用。
  4. 测试项目向前端应用发送 HTTP 请求。

测试项目启动 AppHost 后,由它编排所有依赖资源——无论资源是什么类型。测试项目可以向前端发请求,前端依赖 API,API 依赖数据库;一次成功的请求就证明了「前端能调通 API」以及「API 能取到数据库数据」。

不支持模拟与替换服务

Aspire 测试不支持对依赖注入中的服务做 mock、替换,因为测试运行在独立进程中。需要这类能力时,请改用 WebApplicationFactory<T>。

何时使用 ​

适合使用 Aspire 测试的场景:

  • 验证分布式应用的端到端功能。
  • 确认多个服务与资源(例如数据库)之间的交互在真实条件下行为正确。
  • 验证数据持久化以及与真实外部依赖(例如 PostgreSQL)的集成。

如果你的目标是测试单个项目、在内存中运行组件、或 mock 外部依赖,请使用 WebApplicationFactory<T>。

进程隔离带来的约束

由于应用以独立进程运行,测试代码无法直接访问应用内部的服务或组件。您可以通过环境变量或配置影响应用行为,但内部状态与服务仍封装在各自进程中。

配置选项 ​

DistributedApplicationTestingBuilder 提供多种配置选项。

关闭端口随机化 ​

默认使用随机端口,以支持多个实例并发运行;服务之间通过 Aspire 的服务发现互相定位。如需关闭:

csharp
var builder = await DistributedApplicationTestingBuilder
    .CreateAsync<Projects.MyAppHost>(
    [
        "DcpPublisher:RandomizePorts=false"
    ]);

启用仪表板 ​

测试构建器默认关闭 Aspire 仪表板。如需启用:

csharp
var builder = await DistributedApplicationTestingBuilder
    .CreateAsync<Projects.MyAppHost>(
        args: [],
        configureBuilder: (appOptions, hostSettings) =>
        {
            appOptions.DisableDashboard = false;
        });

调试测试时很有用

测试卡住或断言失败时,打开仪表板能直接看到资源状态、日志与追踪,比逐个加 Console.WriteLine 高效得多。

在测试中访问资源 ​

需求用法
获取 HTTP 客户端app.CreateHttpClient("webfrontend"),可用 endpointName 指定端点。
获取连接字符串app.GetConnectionString("catalogdb") 后交给对应客户端库。
等待资源运行app.ResourceNotifications.WaitForResourceAsync(name, KnownResourceStates.Running, ct)
等待资源健康app.ResourceNotifications.WaitForResourceHealthyAsync(name, ct)

等待时请加超时

始终为等待操作提供超时,避免资源永远无法就绪时测试无限挂起:

csharp
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
await app.ResourceNotifications.WaitForResourceHealthyAsync("webfrontend", cts.Token);

下一步 ​

你觉得这篇文章怎么样?
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
评论
  • 按正序
  • 按倒序
  • 按热度