最初の .NET.NET Aspire テストを記述する
この記事では、テスト プロジェクトを作成し、テストを記述し、.NET.NET Aspire ソリューション用に実行する方法について説明します。 この記事のテストは単体テストではなく、機能テストまたは統合テストです。 .NET .NET Aspire には、.NET リソースの依存関係とその通信をテストするために使用できる、.NET Aspire のバリエーションがいくつか含まれています。 テスト プロジェクト テンプレートは、MSTest、NUnit、および xUnit テスト フレームワークで使用でき、テストの開始点として使用できるサンプル テストが含まれています。
.NET .NET Aspire テスト プロジェクト テンプレートは、📦Aspireに依存します。Hosting.Testing NuGet パッケージ。 このパッケージは、分散アプリケーションのテスト ホストを作成するために使用される DistributedApplicationTestingBuilder クラスを公開します。 分散アプリケーション テスト ビルダーは、DistributedApplication クラスに依存して、アプリ ホストを作成して起動します。
テスト プロジェクトを作成する
.NET
.NET Aspire テスト プロジェクトを作成する最も簡単な方法は、テスト プロジェクト テンプレートを使用することです。 新しい .NET.NET Aspire プロジェクトを開始し、テスト プロジェクトを含める場合、Visual Studio ツールはそのオプションをサポートします。 既存の .NET.NET Aspire プロジェクトにテスト プロジェクトを追加する場合は、dotnet new
コマンドを使用してテスト プロジェクトを作成できます。
dotnet new aspire-xunit
dotnet new aspire-mstest
dotnet new aspire-nunit
詳細については、.NET CLI dotnet new コマンドのドキュメントを参照してください。
テスト プロジェクトを調べる
次のサンプル テスト プロジェクトは、.NET.NET Aspire Starter Application テンプレートの一部として作成されました。 使い慣れていない場合は、「クイック スタート: .NET.NET Aspire プロジェクトの最初のをビルドする」を参照してください。 .NET .NET Aspire テスト プロジェクトは、ターゲット アプリ ホストに対するプロジェクト参照の依存関係を受け取ります。 テンプレート プロジェクトについて考えてみましょう。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Aspire.Hosting.Testing" Version="9.0.0" />
<PackageReference Include="coverlet.collector" Version="6.0.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AspireApp.AppHost\AspireApp.AppHost.csproj" />
</ItemGroup>
<ItemGroup>
<Using Include="System.Net" />
<Using Include="Microsoft.Extensions.DependencyInjection" />
<Using Include="Aspire.Hosting.ApplicationModel" />
<Using Include="Aspire.Hosting.Testing" />
<Using Include="Xunit" />
</ItemGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<PropertyGroup>
<EnableMSTestRunner>true</EnableMSTestRunner>
<OutputType>Exe</OutputType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Aspire.Hosting.Testing" Version="9.0.0" />
<PackageReference Include="MSTest" Version="3.6.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AspireApp.AppHost\AspireApp.AppHost.csproj" />
</ItemGroup>
<ItemGroup>
<Using Include="System.Net" />
<Using Include="Microsoft.Extensions.DependencyInjection" />
<Using Include="Aspire.Hosting.ApplicationModel" />
<Using Include="Aspire.Hosting.Testing" />
<Using Include="Microsoft.VisualStudio.TestTools.UnitTesting" />
</ItemGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Aspire.Hosting.Testing" Version="9.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="NUnit" Version="4.3.1" />
<PackageReference Include="NUnit.Analyzers" Version="4.5.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AspireApp.AppHost\AspireApp.AppHost.csproj" />
</ItemGroup>
<ItemGroup>
<Using Include="System.Net" />
<Using Include="Microsoft.Extensions.DependencyInjection" />
<Using Include="Aspire.Hosting.ApplicationModel" />
<Using Include="Aspire.Hosting.Testing" />
<Using Include="NUnit.Framework" />
</ItemGroup>
</Project>
上記のプロジェクト ファイルはかなり標準的です。
PackageReference
📦のための Aspire があり、Hosting.Testing NuGet パッケージには、.NET.NET Aspire プロジェクトのテストを記述するために必要な型が含まれています。
テンプレート テスト プロジェクトには、1 つのテストを含む IntegrationTest1
クラスが含まれています。 このテストでは、次のシナリオが検証されます。
- アプリ ホストが正常に作成され、開始されました。
-
webfrontend
リソースが使用可能で実行中です。 -
webfrontend
リソースに対して HTTP 要求を行い、正常な応答を返すことができます (HTTP 200 OK)。
次のテスト クラスについて考えてみましょう。
namespace AspireApp.Tests;
public class IntegrationTest1
{
[Fact]
public async Task GetWebResourceRootReturnsOkStatusCode()
{
// Arrange
var appHost = await DistributedApplicationTestingBuilder
.CreateAsync<Projects.AspireApp_AppHost>();
appHost.Services.ConfigureHttpClientDefaults(clientBuilder =>
{
clientBuilder.AddStandardResilienceHandler();
});
// To output logs to the xUnit.net ITestOutputHelper,
// consider adding a package from https://www.nuget.org/packages?q=xunit+logging
await using var app = await appHost.BuildAsync();
var resourceNotificationService = app.Services
.GetRequiredService<ResourceNotificationService>();
await app.StartAsync();
// Act
var httpClient = app.CreateHttpClient("webfrontend");
await resourceNotificationService.WaitForResourceAsync(
"webfrontend",
KnownResourceStates.Running
)
.WaitAsync(TimeSpan.FromSeconds(30));
var response = await httpClient.GetAsync("/");
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
}
namespace AspireApp.Tests;
[TestClass]
public class IntegrationTest1
{
[TestMethod]
public async Task GetWebResourceRootReturnsOkStatusCode()
{
// Arrange
var appHost = await DistributedApplicationTestingBuilder
.CreateAsync<Projects.AspireApp_AppHost>();
appHost.Services.ConfigureHttpClientDefaults(clientBuilder =>
{
clientBuilder.AddStandardResilienceHandler();
});
await using var app = await appHost.BuildAsync();
var resourceNotificationService = app.Services
.GetRequiredService<ResourceNotificationService>();
await app.StartAsync();
// Act
var httpClient = app.CreateHttpClient("webfrontend");
await resourceNotificationService.WaitForResourceAsync(
"webfrontend",
KnownResourceStates.Running
)
.WaitAsync(TimeSpan.FromSeconds(30));
var response = await httpClient.GetAsync("/");
// Assert
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
}
namespace AspireApp.Tests;
public class IntegrationTest1
{
[Test]
public async Task GetWebResourceRootReturnsOkStatusCode()
{
// Arrange
var appHost = await DistributedApplicationTestingBuilder
.CreateAsync<Projects.AspireApp_AppHost>();
appHost.Services.ConfigureHttpClientDefaults(clientBuilder =>
{
clientBuilder.AddStandardResilienceHandler();
});
await using var app = await appHost.BuildAsync();
var resourceNotificationService = app.Services
.GetRequiredService<ResourceNotificationService>();
await app.StartAsync();
// Act
var httpClient = app.CreateHttpClient("webfrontend");
await resourceNotificationService.WaitForResourceAsync(
"webfrontend",
KnownResourceStates.Running
)
.WaitAsync(TimeSpan.FromSeconds(30));
var response = await httpClient.GetAsync("/");
// Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
}
}
上記のコード:
-
DistributedApplicationTestingBuilder.CreateAsync API を使用して、アプリ ホストを非同期的に作成します。
-
appHost
は、アプリ ホストを表すIDistributedApplicationTestingBuilder
のインスタンスです。 -
appHost
インスタンスには、標準の HTTP 回復性ハンドラーを使用してサービス コレクションが構成されています。 詳細については、「回復性の高い HTTP アプリの構築 : 主要な開発パターン」を参照してください。
-
-
appHost
では、IDistributedApplicationTestingBuilder.BuildAsync(CancellationToken) メソッドが呼び出され、DistributedApplication
インスタンスがapp
として返されます。-
app
のサービスプロバイダがResourceNotificationServiceインスタンスを取得します。 -
app
は非同期的に開始されます。
-
-
HttpClientを呼び出すことによって、
webfrontend
リソースのapp.CreateHttpClient
が作成されます。 -
resourceNotificationService
は、webfrontend
リソースが使用可能で実行されるのを待機するために使用されます。 - 単純な HTTP GET 要求は、
webfrontend
リソースのルートに対して行われます。 - テストでは、応答状態コードが
OK
されていることをアサートします。
リソース環境変数をテストする
.NET
.NET Aspire ソリューションでリソースとその明示的な依存関係をさらにテストするには、環境変数が正しく挿入されていることをアサートできます。 次の例では、webfrontend
リソースに、apiservice
リソースに解決される HTTPS 環境変数があることをテストする方法を示します。
using Aspire.Hosting;
namespace AspireApp.Tests;
public class EnvVarTests
{
[Fact]
public async Task WebResourceEnvVarsResolveToApiService()
{
// Arrange
var appHost = await DistributedApplicationTestingBuilder
.CreateAsync<Projects.AspireApp_AppHost>();
var frontend = (IResourceWithEnvironment)appHost.Resources
.Single(static r => r.Name == "webfrontend");
// Act
var envVars = await frontend.GetEnvironmentVariableValuesAsync(
DistributedApplicationOperation.Publish);
// Assert
Assert.Contains(envVars, static (kvp) =>
{
var (key, value) = kvp;
return key is "services__apiservice__https__0"
&& value is "{apiservice.bindings.https.url}";
});
}
}
using Aspire.Hosting;
namespace AspireApp.Tests;
[TestClass]
public class EnvVarTests
{
[TestMethod]
public async Task WebResourceEnvVarsResolveToApiService()
{
// Arrange
var appHost = await DistributedApplicationTestingBuilder
.CreateAsync<Projects.AspireApp_AppHost>();
var frontend = (IResourceWithEnvironment)appHost.Resources
.Single(static r => r.Name == "webfrontend");
// Act
var envVars = await frontend.GetEnvironmentVariableValuesAsync(
DistributedApplicationOperation.Publish);
// Assert
CollectionAssert.Contains(envVars,
new KeyValuePair<string, string>(
key: "services__apiservice__https__0",
value: "{apiservice.bindings.https.url}"));
}
}
using Aspire.Hosting;
namespace AspireApp.Tests;
public class EnvVarTests
{
[Test]
public async Task WebResourceEnvVarsResolveToApiService()
{
// Arrange
var appHost = await DistributedApplicationTestingBuilder
.CreateAsync<Projects.AspireApp_AppHost>();
var frontend = (IResourceWithEnvironment)appHost.Resources
.Single(static r => r.Name == "webfrontend");
// Act
var envVars = await frontend.GetEnvironmentVariableValuesAsync(
DistributedApplicationOperation.Publish);
// Assert
Assert.That(envVars, Does.Contain(
new KeyValuePair<string, string>(
key: "services__apiservice__https__0",
value: "{apiservice.bindings.https.url}")));
}
}
上記のコード:
- DistributedApplicationTestingBuilder.CreateAsync API を使用して、アプリ ホストを非同期的に作成します。
-
builder
インスタンスは、IResourceWithEnvironmentから "webfrontend" という名前の IDistributedApplicationTestingBuilder.Resources インスタンスを取得するために使用されます。 -
webfrontend
リソースは、GetEnvironmentVariableValuesAsync を呼び出して構成された環境変数を取得するために使用されます。 -
DistributedApplicationOperation.Publish 引数は、バインド式としてリソースに発行される環境変数を指定するために
GetEnvironmentVariableValuesAsync
を呼び出すときに渡されます。 - 返された環境変数を使用して、
webfrontend
リソースに、apiservice
リソースに解決される HTTPS 環境変数があることをテストによってアサートします。
概要
.NET Aspire テスト プロジェクト テンプレートを使用すると、.NET Aspire ソリューションのテスト プロジェクトを簡単に作成できます。 テンプレート プロジェクトには、テストの開始点として使用できるサンプル テストが含まれています。
DistributedApplicationTestingBuilder
は、WebApplicationFactory<TEntryPoint>の ASP.NET Core に慣れたパターンに従います。 これにより、分散アプリケーションのテスト ホストを作成し、それに対してテストを実行できます。
最後に、DistributedApplicationTestingBuilder
を使用すると、既定ですべてのリソース ログが DistributedApplication
にリダイレクトされます。 リソース ログのリダイレクトにより、リソースが正しくログ記録されていることをアサートするシナリオが可能になります。
関連項目
- .NET を使用して、 で C# の単体テストをする
- MSTest の概要
- C#でのNUnitと .NET Core を使用した単体テスト
.NET Aspire