diff --git a/Directory.Packages.props b/Directory.Packages.props
index 5f844ff..f725fd2 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -41,6 +41,7 @@
+
diff --git a/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/PgEntityTableRepository_Tests.cs b/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/PgEntityTableRepository_Tests.cs
index 3552fcd..ae0fc2d 100644
--- a/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/PgEntityTableRepository_Tests.cs
+++ b/tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/PgEntityTableRepository_Tests.cs
@@ -4,6 +4,7 @@
using CommunityToolkit.Datasync.TestCommon;
using CommunityToolkit.Datasync.TestCommon.Databases;
+using CommunityToolkit.Datasync.TestCommon.Fixtures;
using Microsoft.EntityFrameworkCore;
using Xunit.Abstractions;
@@ -13,7 +14,7 @@ namespace CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test;
[ExcludeFromCodeCoverage]
[Collection("LiveTestsCollection")]
-public class PgEntityTableRepository_Tests(DatabaseFixture fixture, ITestOutputHelper output) : RepositoryTests, IAsyncLifetime
+public class PgEntityTableRepository_Tests(PostgreSqlDatabaseFixture fixture, ITestOutputHelper output) : RepositoryTests, IClassFixture, IAsyncLifetime
{
#region Setup
private readonly Random random = new();
@@ -21,11 +22,8 @@ public class PgEntityTableRepository_Tests(DatabaseFixture fixture, ITestOutputH
public async Task InitializeAsync()
{
- if (!string.IsNullOrEmpty(ConnectionStrings.PgSql))
- {
- Context = await PgDbContext.CreateContextAsync(ConnectionStrings.PgSql, output);
- this.movies = await Context.Movies.AsNoTracking().ToListAsync();
- }
+ Context = await PgDbContext.CreateContextAsync(fixture.ConnectionString, output);
+ this.movies = await Context.Movies.AsNoTracking().ToListAsync();
}
public async Task DisposeAsync()
@@ -38,7 +36,7 @@ public async Task DisposeAsync()
private PgDbContext Context { get; set; }
- protected override bool CanRunLiveTests() => !string.IsNullOrEmpty(ConnectionStrings.PgSql);
+ protected override bool CanRunLiveTests() => true;
protected override async Task GetEntityAsync(string id)
=> await Context.Movies.AsNoTracking().SingleOrDefaultAsync(m => m.Id == id);
diff --git a/tests/CommunityToolkit.Datasync.Server.Test/Live/PgSQL_Controller_Tests.cs b/tests/CommunityToolkit.Datasync.Server.Test/Live/PgSQL_Controller_Tests.cs
index 43ef6cc..431c9b2 100644
--- a/tests/CommunityToolkit.Datasync.Server.Test/Live/PgSQL_Controller_Tests.cs
+++ b/tests/CommunityToolkit.Datasync.Server.Test/Live/PgSQL_Controller_Tests.cs
@@ -5,6 +5,7 @@
using CommunityToolkit.Datasync.Server.EntityFrameworkCore;
using CommunityToolkit.Datasync.Server.Test.Helpers;
using CommunityToolkit.Datasync.TestCommon.Databases;
+using CommunityToolkit.Datasync.TestCommon.Fixtures;
using Microsoft.EntityFrameworkCore;
using Xunit.Abstractions;
@@ -12,7 +13,7 @@ namespace CommunityToolkit.Datasync.Server.Test.Live;
[ExcludeFromCodeCoverage]
[Collection("LiveTestsCollection")]
-public class PgSQL_Controller_Tests(DatabaseFixture fixture, ITestOutputHelper output) : LiveControllerTests, IAsyncLifetime
+public class PgSQL_Controller_Tests(PostgreSqlDatabaseFixture fixture, ITestOutputHelper output) : LiveControllerTests, IClassFixture, IAsyncLifetime
{
#region Setup
private readonly Random random = new();
@@ -20,16 +21,8 @@ public class PgSQL_Controller_Tests(DatabaseFixture fixture, ITestOutputHelper o
public async Task InitializeAsync()
{
- if (!string.IsNullOrEmpty(ConnectionStrings.PgSql))
- {
- // Note: we don't clear entities on every run to speed up the test runs. This can only be done because
- // the tests are read-only (associated with the query and get capabilities). If the test being run writes
- // to the database then change clearEntities to true.
- output.WriteLine($"PgIsInitialized = {fixture.PgIsInitialized}");
- Context = await PgDbContext.CreateContextAsync(ConnectionStrings.PgSql, output, clearEntities: !fixture.PgIsInitialized);
- this.movies = Context.Movies.AsNoTracking().ToList();
- fixture.PgIsInitialized = true;
- }
+ Context = await PgDbContext.CreateContextAsync(fixture.ConnectionString, output);
+ this.movies = await Context.Movies.AsNoTracking().ToListAsync();
}
public async Task DisposeAsync()
@@ -44,7 +37,7 @@ public async Task DisposeAsync()
protected override string DriverName { get; } = "PgSQL";
- protected override bool CanRunLiveTests() => !string.IsNullOrEmpty(ConnectionStrings.PgSql);
+ protected override bool CanRunLiveTests() => true;
protected override async Task GetEntityAsync(string id)
=> await Context.Movies.AsNoTracking().SingleOrDefaultAsync(m => m.Id == id);
diff --git a/tests/CommunityToolkit.Datasync.TestCommon/CommunityToolkit.Datasync.TestCommon.csproj b/tests/CommunityToolkit.Datasync.TestCommon/CommunityToolkit.Datasync.TestCommon.csproj
index 7695fb3..7e8f0d9 100644
--- a/tests/CommunityToolkit.Datasync.TestCommon/CommunityToolkit.Datasync.TestCommon.csproj
+++ b/tests/CommunityToolkit.Datasync.TestCommon/CommunityToolkit.Datasync.TestCommon.csproj
@@ -21,6 +21,7 @@
+
diff --git a/tests/CommunityToolkit.Datasync.TestCommon/Databases/ConnectionStrings.cs b/tests/CommunityToolkit.Datasync.TestCommon/Databases/ConnectionStrings.cs
index dfca137..16c9b4b 100644
--- a/tests/CommunityToolkit.Datasync.TestCommon/Databases/ConnectionStrings.cs
+++ b/tests/CommunityToolkit.Datasync.TestCommon/Databases/ConnectionStrings.cs
@@ -11,7 +11,6 @@ public static class ConnectionStrings
public static readonly string CosmosDb = Environment.GetEnvironmentVariable("COSMOS_CONNECTION_STRING");
public static readonly string MongoCommunity = Environment.GetEnvironmentVariable("MONGOACI_CONNECTION_STRING");
public static readonly string CosmosMongo = Environment.GetEnvironmentVariable("MONGO_CONNECTION_STRING");
- public static readonly string PgSql = Environment.GetEnvironmentVariable("PGSQL_CONNECTION_STRING");
public static readonly string Service = Environment.GetEnvironmentVariable("SERVICE_ENDPOINT");
public static readonly bool EnableLogging = (Environment.GetEnvironmentVariable("ENABLE_SQL_LOGGING") ?? "false") == "true";
}
\ No newline at end of file
diff --git a/tests/CommunityToolkit.Datasync.TestCommon/Fixtures/MySqlTestFixture.cs b/tests/CommunityToolkit.Datasync.TestCommon/Fixtures/MySqlTestFixture.cs
deleted file mode 100644
index e69de29..0000000
diff --git a/tests/CommunityToolkit.Datasync.TestCommon/Fixtures/PostgreSqlDatabaseFixture.cs b/tests/CommunityToolkit.Datasync.TestCommon/Fixtures/PostgreSqlDatabaseFixture.cs
new file mode 100644
index 0000000..d1a21ac
--- /dev/null
+++ b/tests/CommunityToolkit.Datasync.TestCommon/Fixtures/PostgreSqlDatabaseFixture.cs
@@ -0,0 +1,51 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using DotNet.Testcontainers.Builders;
+using Testcontainers.PostgreSql;
+using Xunit;
+
+namespace CommunityToolkit.Datasync.TestCommon.Fixtures;
+
+///
+/// A test fixture for implementing a PostgreSQL database using Testcontainers.
+///
+[ExcludeFromCodeCoverage]
+public class PostgreSqlDatabaseFixture : IAsyncLifetime
+{
+ private readonly PostgreSqlContainer _container;
+
+ public PostgreSqlDatabaseFixture()
+ {
+ this._container = new PostgreSqlBuilder()
+ .WithImage("postgres:17-alpine")
+ .WithCleanUp(true)
+ .WithUsername("testuser")
+ .WithPassword("testpassword")
+ .WithDatabase("testdb")
+ .WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(5432))
+ .Build();
+ }
+
+ ///
+ public async Task DisposeAsync()
+ {
+ if (this._container is not null)
+ {
+ await this._container.DisposeAsync();
+ }
+ }
+
+ ///
+ public async Task InitializeAsync()
+ {
+ await this._container.StartAsync();
+ ConnectionString = this._container.GetConnectionString();
+ }
+
+ ///
+ /// The connection string for the MySQL database.
+ ///
+ public string ConnectionString { get; private set; } = string.Empty;
+}