Skip to content

Commit 5c624a3

Browse files
authored
(#345) Added PostgreSql TestContainer fixture (#350)
1 parent b59bf2a commit 5c624a3

File tree

7 files changed

+63
-20
lines changed

7 files changed

+63
-20
lines changed

Directory.Packages.props

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
<PackageVersion Include="System.Text.RegularExpressions" Version="4.3.1" />
4242
<PackageVersion Include="System.Threading.Tasks.Dataflow" Version="9.0.4" />
4343
<PackageVersion Include="TestContainers.MySql" Version="4.4.0" />
44+
<PackageVersion Include="TestContainers.PostgreSql" Version="4.4.0" />
4445
<PackageVersion Include="xunit" Version="2.9.3" />
4546
<PackageVersion Include="xunit.runner.visualstudio" Version="3.0.2" />
4647
<PackageVersion Include="coverlet.collector" Version="6.0.4" />

tests/CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test/PgEntityTableRepository_Tests.cs

+5-7
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
using CommunityToolkit.Datasync.TestCommon;
66
using CommunityToolkit.Datasync.TestCommon.Databases;
7+
using CommunityToolkit.Datasync.TestCommon.Fixtures;
78
using Microsoft.EntityFrameworkCore;
89
using Xunit.Abstractions;
910

@@ -13,19 +14,16 @@ namespace CommunityToolkit.Datasync.Server.EntityFrameworkCore.Test;
1314

1415
[ExcludeFromCodeCoverage]
1516
[Collection("LiveTestsCollection")]
16-
public class PgEntityTableRepository_Tests(DatabaseFixture fixture, ITestOutputHelper output) : RepositoryTests<PgEntityMovie>, IAsyncLifetime
17+
public class PgEntityTableRepository_Tests(PostgreSqlDatabaseFixture fixture, ITestOutputHelper output) : RepositoryTests<PgEntityMovie>, IClassFixture<PostgreSqlDatabaseFixture>, IAsyncLifetime
1718
{
1819
#region Setup
1920
private readonly Random random = new();
2021
private List<PgEntityMovie> movies = [];
2122

2223
public async Task InitializeAsync()
2324
{
24-
if (!string.IsNullOrEmpty(ConnectionStrings.PgSql))
25-
{
26-
Context = await PgDbContext.CreateContextAsync(ConnectionStrings.PgSql, output);
27-
this.movies = await Context.Movies.AsNoTracking().ToListAsync();
28-
}
25+
Context = await PgDbContext.CreateContextAsync(fixture.ConnectionString, output);
26+
this.movies = await Context.Movies.AsNoTracking().ToListAsync();
2927
}
3028

3129
public async Task DisposeAsync()
@@ -38,7 +36,7 @@ public async Task DisposeAsync()
3836

3937
private PgDbContext Context { get; set; }
4038

41-
protected override bool CanRunLiveTests() => !string.IsNullOrEmpty(ConnectionStrings.PgSql);
39+
protected override bool CanRunLiveTests() => true;
4240

4341
protected override async Task<PgEntityMovie> GetEntityAsync(string id)
4442
=> await Context.Movies.AsNoTracking().SingleOrDefaultAsync(m => m.Id == id);

tests/CommunityToolkit.Datasync.Server.Test/Live/PgSQL_Controller_Tests.cs

+5-12
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,24 @@
55
using CommunityToolkit.Datasync.Server.EntityFrameworkCore;
66
using CommunityToolkit.Datasync.Server.Test.Helpers;
77
using CommunityToolkit.Datasync.TestCommon.Databases;
8+
using CommunityToolkit.Datasync.TestCommon.Fixtures;
89
using Microsoft.EntityFrameworkCore;
910
using Xunit.Abstractions;
1011

1112
namespace CommunityToolkit.Datasync.Server.Test.Live;
1213

1314
[ExcludeFromCodeCoverage]
1415
[Collection("LiveTestsCollection")]
15-
public class PgSQL_Controller_Tests(DatabaseFixture fixture, ITestOutputHelper output) : LiveControllerTests<PgEntityMovie>, IAsyncLifetime
16+
public class PgSQL_Controller_Tests(PostgreSqlDatabaseFixture fixture, ITestOutputHelper output) : LiveControllerTests<PgEntityMovie>, IClassFixture<PostgreSqlDatabaseFixture>, IAsyncLifetime
1617
{
1718
#region Setup
1819
private readonly Random random = new();
1920
private List<PgEntityMovie> movies = [];
2021

2122
public async Task InitializeAsync()
2223
{
23-
if (!string.IsNullOrEmpty(ConnectionStrings.PgSql))
24-
{
25-
// Note: we don't clear entities on every run to speed up the test runs. This can only be done because
26-
// the tests are read-only (associated with the query and get capabilities). If the test being run writes
27-
// to the database then change clearEntities to true.
28-
output.WriteLine($"PgIsInitialized = {fixture.PgIsInitialized}");
29-
Context = await PgDbContext.CreateContextAsync(ConnectionStrings.PgSql, output, clearEntities: !fixture.PgIsInitialized);
30-
this.movies = Context.Movies.AsNoTracking().ToList();
31-
fixture.PgIsInitialized = true;
32-
}
24+
Context = await PgDbContext.CreateContextAsync(fixture.ConnectionString, output);
25+
this.movies = await Context.Movies.AsNoTracking().ToListAsync();
3326
}
3427

3528
public async Task DisposeAsync()
@@ -44,7 +37,7 @@ public async Task DisposeAsync()
4437

4538
protected override string DriverName { get; } = "PgSQL";
4639

47-
protected override bool CanRunLiveTests() => !string.IsNullOrEmpty(ConnectionStrings.PgSql);
40+
protected override bool CanRunLiveTests() => true;
4841

4942
protected override async Task<PgEntityMovie> GetEntityAsync(string id)
5043
=> await Context.Movies.AsNoTracking().SingleOrDefaultAsync(m => m.Id == id);

tests/CommunityToolkit.Datasync.TestCommon/CommunityToolkit.Datasync.TestCommon.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" />
2222
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" />
2323
<PackageReference Include="TestContainers.MySql" />
24+
<PackageReference Include="TestContainers.PostgreSql" />
2425
</ItemGroup>
2526

2627
<ItemGroup>

tests/CommunityToolkit.Datasync.TestCommon/Databases/ConnectionStrings.cs

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ public static class ConnectionStrings
1111
public static readonly string CosmosDb = Environment.GetEnvironmentVariable("COSMOS_CONNECTION_STRING");
1212
public static readonly string MongoCommunity = Environment.GetEnvironmentVariable("MONGOACI_CONNECTION_STRING");
1313
public static readonly string CosmosMongo = Environment.GetEnvironmentVariable("MONGO_CONNECTION_STRING");
14-
public static readonly string PgSql = Environment.GetEnvironmentVariable("PGSQL_CONNECTION_STRING");
1514
public static readonly string Service = Environment.GetEnvironmentVariable("SERVICE_ENDPOINT");
1615
public static readonly bool EnableLogging = (Environment.GetEnvironmentVariable("ENABLE_SQL_LOGGING") ?? "false") == "true";
1716
}

tests/CommunityToolkit.Datasync.TestCommon/Fixtures/MySqlTestFixture.cs

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using DotNet.Testcontainers.Builders;
6+
using Testcontainers.PostgreSql;
7+
using Xunit;
8+
9+
namespace CommunityToolkit.Datasync.TestCommon.Fixtures;
10+
11+
/// <summary>
12+
/// A test fixture for implementing a PostgreSQL database using Testcontainers.
13+
/// </summary>
14+
[ExcludeFromCodeCoverage]
15+
public class PostgreSqlDatabaseFixture : IAsyncLifetime
16+
{
17+
private readonly PostgreSqlContainer _container;
18+
19+
public PostgreSqlDatabaseFixture()
20+
{
21+
this._container = new PostgreSqlBuilder()
22+
.WithImage("postgres:17-alpine")
23+
.WithCleanUp(true)
24+
.WithUsername("testuser")
25+
.WithPassword("testpassword")
26+
.WithDatabase("testdb")
27+
.WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(5432))
28+
.Build();
29+
}
30+
31+
/// <inheritdoc />
32+
public async Task DisposeAsync()
33+
{
34+
if (this._container is not null)
35+
{
36+
await this._container.DisposeAsync();
37+
}
38+
}
39+
40+
/// <inheritdoc />
41+
public async Task InitializeAsync()
42+
{
43+
await this._container.StartAsync();
44+
ConnectionString = this._container.GetConnectionString();
45+
}
46+
47+
/// <summary>
48+
/// The connection string for the MySQL database.
49+
/// </summary>
50+
public string ConnectionString { get; private set; } = string.Empty;
51+
}

0 commit comments

Comments
 (0)