Skip to Content
Testcontainers ガイド.NET で Testcontainers を使い始める

.NET で Testcontainers を使い始める



コードを入手する

Testcontainers は、Docker コンテナでラップされた実際のサービスを使用して統合テストを簡単かつ軽量な API で構築できるテストライブラリです。Testcontainers を使用すると、本番環境で使用しているサービスと同じ種類のサービスと対話するテストを、モックやインメモリサービスを使用せずに記述できます。

Testcontainers を初めて使用する場合は、Testcontainers とは何か、なぜ使うべきなのか?を読んで、Testcontainersについて詳しく学んでください。

Postgres データベースを使用して .NET アプリケーションをテストするために、Testcontainers をどのように活用できるかを見ていきましょう。

ソリューションファイルを作成し、ソースプロジェクトとテストプロジェクトを準備する

ターミナルまたはお好みの IDE を使用して、.NET のソースプロジェクトとテストプロジェクトを作成します。

$ dotnet new sln -o TestcontainersDemo $ cd TestcontainersDemo $ dotnet new classlib -o CustomerService $ dotnet sln add ./CustomerService/CustomerService.csproj $ dotnet new xunit -o CustomerService.Tests $ dotnet sln add ./CustomerService.Tests/CustomerService.Tests.csproj $ dotnet add ./CustomerService.Tests/CustomerService.Tests.csproj reference ./CustomerService/CustomerService.csproj

プロジェクトが作成されたら、ソースプロジェクトに Npgsql の依存関係を以下のように追加します:

dotnet add ./CustomerService/CustomerService.csproj package Npgsql

これで、ソースプロジェクトとテストプロジェクトには以下の依存関係が含まれているはずです。

ソースプロジェクト

<PackageReference Include="Npgsql" Version="7.0.4" />

テストプロジェクト

<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" /> <PackageReference Include="xunit" Version="2.4.2" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.4.5"/>

Postgres データベースとやり取りするために、Postgres 用の ADO.NET データプロバイダーである Npgsql を追加しました。また、サービスのテストには xUnit を使用します。

ビジネスロジックの実装

顧客情報を管理するための CustomerService クラスを作成します。

まず、以下のように Customer 型を作成します:

namespace Customers; public readonly record struct Customer(long Id, string Name);

ADO.NET の接続パラメータ(接続文字列)を保持するための DbConnectionProvider クラスを作成し、データベース接続を取得するメソッドを以下のように実装します:

using System.Data.Common; using Npgsql; namespace Customers; public sealed class DbConnectionProvider { private readonly string _connectionString; public DbConnectionProvider(string connectionString) { _connectionString = connectionString; } public DbConnection GetConnection() { return new NpgsqlConnection(_connectionString); } }

CustomerService クラスを作成し、以下のコードを追加してください:

namespace Customers; public sealed class CustomerService { private readonly DbConnectionProvider _dbConnectionProvider; public CustomerService(DbConnectionProvider dbConnectionProvider) { _dbConnectionProvider = dbConnectionProvider; CreateCustomersTable(); } public IEnumerable<Customer> GetCustomers() { IList<Customer> customers = new List<Customer>(); using var connection = _dbConnectionProvider.GetConnection(); using var command = connection.CreateCommand(); command.CommandText = "SELECT id, name FROM customers"; command.Connection?.Open(); using var dataReader = command.ExecuteReader(); while (dataReader.Read()) { var id = dataReader.GetInt64(0); var name = dataReader.GetString(1); customers.Add(new Customer(id, name)); } return customers; } public void Create(Customer customer) { using var connection = _dbConnectionProvider.GetConnection(); using var command = connection.CreateCommand(); var id = command.CreateParameter(); id.ParameterName = "@id"; id.Value = customer.Id; var name = command.CreateParameter(); name.ParameterName = "@name"; name.Value = customer.Name; command.CommandText = "INSERT INTO customers (id, name) VALUES(@id, @name)"; command.Parameters.Add(id); command.Parameters.Add(name); command.Connection?.Open(); command.ExecuteNonQuery(); } private void CreateCustomersTable() { using var connection = _dbConnectionProvider.GetConnection(); using var command = connection.CreateCommand(); command.CommandText = "CREATE TABLE IF NOT EXISTS customers (id BIGINT NOT NULL, name VARCHAR NOT NULL, PRIMARY KEY (id))"; command.Connection?.Open(); command.ExecuteNonQuery(); } }

CustomerService クラスでは、顧客情報を管理するためのいくつかのメソッドが実装されています。それぞれの動作を以下に説明します。

  • _dbConnectionProvider.GetConnection(): ADO.NET を使用してデータベース接続を取得します。

  • CreateCustomersTable() メソッド: customers テーブルが存在しない場合に作成します。

  • GetCustomers() メソッド: customers テーブルからすべての行を取得し、それを Customer オブジェクトに変換してリストとして返します。

  • Create(Customer) メソッド: 新しい顧客レコードをデータベースに挿入します。

次に、Testcontainers を活用して、CustomerService のロジックをどのようにテストできるかを見ていきましょう。

Testcontainers の依存関係を追加

Testcontainers を使用したテストを書く前に、テストプロジェクトに Testcontainers の PostgreSQL モジュール依存関係を以下のように追加します:

dotnet add ./CustomerService.Tests/CustomerService.Tests.csproj package Testcontainers.PostgreSql

これで、テストプロジェクトに Testcontainers.PostgreSql の依存関係が以下のように追加されているはずです:

私たちのアプリケーションでは Postgres データベースを使用しているため、テスト依存関係として Testcontainers の Postgres モジュールを追加しました。

Testcontainers を使用したテストの作成

テストプロジェクトに CustomerServiceTest クラスを作成し、以下のコードを追加してください:

using Testcontainers.PostgreSql; namespace Customers.Tests; public sealed class CustomerServiceTest : IAsyncLifetime { private readonly PostgreSqlContainer _postgres = new PostgreSqlBuilder() .WithImage("postgres:15-alpine") .Build(); public Task InitializeAsync() { return _postgres.StartAsync(); } public Task DisposeAsync() { return _postgres.DisposeAsync().AsTask(); } [Fact] public void ShouldReturnTwoCustomers() { // Given var customerService = new CustomerService(new DbConnectionProvider(_postgres.GetConnectionString())); // When customerService.Create(new Customer(1, "George")); customerService.Create(new Customer(2, "John")); var customers = customerService.GetCustomers(); // Then Assert.Equal(2, customers.Count()); } }

CustomerServiceTest クラスのコードを理解していきましょう。

  • PostgreSqlContainer の宣言: Postgres ビルダーに Docker イメージ名 postgres:15-alpine を渡して PostgreSqlContainer を宣言します。

  • Postgres コンテナの起動: Postgres コンテナは、xUnit.netIAsyncLifetime インターフェースを使用して起動されます。このインターフェースは、テストクラスが作成された直後に InitializeAsync メソッドを実行します。

  • ShouldReturnTwoCustomers() テスト

    • CustomerService を初期化します。
    • データベースに 2 件の顧客レコードを挿入します。
    • 顧客テーブルのすべての行を取得し、顧客数が期待通りであることを検証します。
  • Postgres コンテナの破棄: テストメソッドの実行後に DisposeAsync() メンバーが実行され、Postgres コンテナが破棄されます。

以下のコマンドを使用してテストを実行します:

dotnet test

CustomerService テストを実行すると、出力に次の動作が表示されます:

  • Testcontainers が DockerHub から Postgres Docker イメージを取得(ローカルにイメージがない場合)
  • コンテナの起動
  • テストの実行

これで、Testcontainers を使用した最初のテストが実行されました!

まとめ

Testcontainers for .NET ライブラリを使用して、Postgres データベースを用いた .NET アプリケーションのテスト方法を学びました。

Testcontainers を使用した統合テストの記述方法は、IDE から実行できる単体テストの記述方法と非常に似ています。また、チームメンバーはプロジェクトをクローンし、自分のコンピュータに Postgres をインストールせずにテストを実行できます。

Postgres 以外にも、Testcontainers は多くの一般的に使用される SQL データベース、NoSQL データベース、メッセージングキューなどの専用モジュールを提供しています。Testcontainers を使用して、テストのためにあらゆるコンテナ化された依存関係を実行できます!

Testcontainers の詳細については、https://testcontainers.com をご覧ください。

参考資料

Last updated on