Skip to content

Commit 35be82d

Browse files
committed
[WIP] Testcontainers.Xunit explicit builder
TODO: explore how we can move from parameterless contrsuctor to explicit creation of the builders. Idea: first step = new `protected virtual TBuilderEntity Configure()` that use reflection and obsolete the Configure method that takes a builder. Next step = make the new Configure() method abstract instead of virtual.
1 parent 2218693 commit 35be82d

19 files changed

Lines changed: 99 additions & 82 deletions

File tree

src/Testcontainers.Xunit/ContainerFixture.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace Testcontainers.Xunit;
99
/// <typeparam name="TBuilderEntity">The builder entity.</typeparam>
1010
/// <typeparam name="TContainerEntity">The container entity.</typeparam>
1111
[PublicAPI]
12-
public class ContainerFixture<TBuilderEntity, TContainerEntity>(IMessageSink messageSink)
12+
public abstract class ContainerFixture<TBuilderEntity, TContainerEntity>(IMessageSink messageSink)
1313
: ContainerLifetime<TBuilderEntity, TContainerEntity>(new MessageSinkLogger(messageSink))
14-
where TBuilderEntity : IContainerBuilder<TBuilderEntity, TContainerEntity, IContainerConfiguration>, new()
14+
where TBuilderEntity : IContainerBuilder<TBuilderEntity, TContainerEntity, IContainerConfiguration>
1515
where TContainerEntity : IContainer;

src/Testcontainers.Xunit/ContainerLifetime.cs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace Testcontainers.Xunit;
66
/// <typeparam name="TBuilderEntity">The builder entity.</typeparam>
77
/// <typeparam name="TContainerEntity">The container entity.</typeparam>
88
public abstract class ContainerLifetime<TBuilderEntity, TContainerEntity> : IAsyncLifetime
9-
where TBuilderEntity : IContainerBuilder<TBuilderEntity, TContainerEntity, IContainerConfiguration>, new()
9+
where TBuilderEntity : IContainerBuilder<TBuilderEntity, TContainerEntity, IContainerConfiguration>
1010
where TContainerEntity : IContainer
1111
{
1212
private readonly Lazy<TContainerEntity> _container;
@@ -16,7 +16,7 @@ public abstract class ContainerLifetime<TBuilderEntity, TContainerEntity> : IAsy
1616

1717
protected ContainerLifetime(ILogger logger)
1818
{
19-
_container = new Lazy<TContainerEntity>(() => Configure(new TBuilderEntity().WithLogger(logger)).Build());
19+
_container = new Lazy<TContainerEntity>(() => Configure().WithLogger(logger).Build());
2020
}
2121

2222
/// <summary>
@@ -48,6 +48,28 @@ await DisposeAsyncCore()
4848
}
4949
#endif
5050

51+
/// <summary>
52+
/// Configures the container instance.
53+
/// </summary>
54+
/// <example>
55+
/// <code>
56+
/// public class MariaDbRootUserFixture(IMessageSink messageSink) : DbContainerFixture&lt;MariaDbBuilder, MariaDbContainer&gt;(messageSink)
57+
/// {
58+
/// public override DbProviderFactory DbProviderFactory =&gt; MySqlConnectorFactory.Instance;
59+
/// <br />
60+
/// protected override MariaDbBuilder Configure()
61+
/// {
62+
/// return new MariaDbBuilder("mariadb:12").WithUsername("root");
63+
/// }
64+
/// }
65+
/// </code>
66+
/// </example>
67+
/// <returns>A configured instance of <typeparamref name="TBuilderEntity" />.</returns>
68+
protected virtual TBuilderEntity Configure()
69+
{
70+
return Activator.CreateInstance<TBuilderEntity>();
71+
}
72+
5173
/// <summary>
5274
/// Extension method to further configure the container instance.
5375
/// </summary>
@@ -66,6 +88,7 @@ await DisposeAsyncCore()
6688
/// </example>
6789
/// <param name="builder">The container builder to configure.</param>
6890
/// <returns>A configured instance of <typeparamref name="TBuilderEntity" />.</returns>
91+
[Obsolete("This method is obsolete and will be removed. Use the parameterless Configure() method and create the builder explicitly instead.")]
6992
protected virtual TBuilderEntity Configure(TBuilderEntity builder)
7093
{
7194
return builder;

src/Testcontainers.Xunit/ContainerTest.cs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,10 @@ namespace Testcontainers.Xunit;
55
/// A logger is automatically configured to write messages to xUnit's <see cref="ITestOutputHelper" />.
66
/// </summary>
77
/// <param name="testOutputHelper">An optional <see cref="ITestOutputHelper" /> where the logs are written to. Pass <c>null</c> to ignore logs.</param>
8-
/// <param name="configure">An optional callback to configure the container.</param>
98
/// <typeparam name="TBuilderEntity">The builder entity.</typeparam>
109
/// <typeparam name="TContainerEntity">The container entity.</typeparam>
1110
[PublicAPI]
12-
public abstract class ContainerTest<TBuilderEntity, TContainerEntity>(ITestOutputHelper testOutputHelper, Func<TBuilderEntity, TBuilderEntity> configure = null)
11+
public abstract class ContainerTest<TBuilderEntity, TContainerEntity>(ITestOutputHelper testOutputHelper)
1312
: ContainerLifetime<TBuilderEntity, TContainerEntity>(new TestOutputLogger(testOutputHelper))
14-
where TBuilderEntity : IContainerBuilder<TBuilderEntity, TContainerEntity, IContainerConfiguration>, new()
15-
where TContainerEntity : IContainer
16-
{
17-
protected override TBuilderEntity Configure(TBuilderEntity builder) => configure != null ? configure(builder) : builder;
18-
}
13+
where TBuilderEntity : IContainerBuilder<TBuilderEntity, TContainerEntity, IContainerConfiguration>
14+
where TContainerEntity : IContainer;

src/Testcontainers.Xunit/DbContainerFixture.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace Testcontainers.Xunit;
1010
[PublicAPI]
1111
public abstract class DbContainerFixture<TBuilderEntity, TContainerEntity>(IMessageSink messageSink)
1212
: ContainerFixture<TBuilderEntity, TContainerEntity>(messageSink), IDbContainerTestMethods
13-
where TBuilderEntity : IContainerBuilder<TBuilderEntity, TContainerEntity, IContainerConfiguration>, new()
13+
where TBuilderEntity : IContainerBuilder<TBuilderEntity, TContainerEntity, IContainerConfiguration>
1414
where TContainerEntity : IContainer, IDatabaseContainer
1515
{
1616
private DbContainerTestMethods _testMethods;

src/Testcontainers.Xunit/DbContainerTest.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ namespace Testcontainers.Xunit;
77
/// <typeparam name="TBuilderEntity">The builder entity.</typeparam>
88
/// <typeparam name="TContainerEntity">The container entity.</typeparam>
99
[PublicAPI]
10-
public abstract class DbContainerTest<TBuilderEntity, TContainerEntity>(ITestOutputHelper testOutputHelper, Func<TBuilderEntity, TBuilderEntity> configure = null)
11-
: ContainerTest<TBuilderEntity, TContainerEntity>(testOutputHelper, configure), IDbContainerTestMethods
12-
where TBuilderEntity : IContainerBuilder<TBuilderEntity, TContainerEntity, IContainerConfiguration>, new()
10+
public abstract class DbContainerTest<TBuilderEntity, TContainerEntity>(ITestOutputHelper testOutputHelper)
11+
: ContainerTest<TBuilderEntity, TContainerEntity>(testOutputHelper), IDbContainerTestMethods
12+
where TBuilderEntity : IContainerBuilder<TBuilderEntity, TContainerEntity, IContainerConfiguration>
1313
where TContainerEntity : IContainer, IDatabaseContainer
1414
{
1515
private DbContainerTestMethods _testMethods;

tests/Testcontainers.Cassandra.Tests/CassandraContainerTest.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ public class CassandraDefaultFixture(IMessageSink messageSink)
6363
protected override CassandraBuilder Configure(CassandraBuilder builder)
6464
=> builder.WithImage(TestSession.GetImageFromDockerfile());
6565

66+
protected override CassandraBuilder Configure()
67+
=> new CassandraBuilder(TestSession.GetImageFromDockerfile());
68+
6669
public override DbProviderFactory DbProviderFactory
6770
=> CqlProviderFactory.Instance;
6871
}
@@ -71,8 +74,8 @@ public override DbProviderFactory DbProviderFactory
7174
public class CassandraWaitForDatabaseFixture(IMessageSink messageSink)
7275
: CassandraDefaultFixture(messageSink)
7376
{
74-
protected override CassandraBuilder Configure(CassandraBuilder builder)
75-
=> builder.WithImage(TestSession.GetImageFromDockerfile()).WithWaitStrategy(Wait.ForUnixContainer().UntilDatabaseIsAvailable(DbProviderFactory));
77+
protected override CassandraBuilder Configure()
78+
=> base.Configure().WithWaitStrategy(Wait.ForUnixContainer().UntilDatabaseIsAvailable(DbProviderFactory));
7679
}
7780

7881
[UsedImplicitly]

tests/Testcontainers.ClickHouse.Tests/ClickHouseContainerTest.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ public async Task ExecScriptReturnsSuccessful()
3535
public class ClickHouseDefaultFixture(IMessageSink messageSink)
3636
: DbContainerFixture<ClickHouseBuilder, ClickHouseContainer>(messageSink)
3737
{
38-
protected override ClickHouseBuilder Configure(ClickHouseBuilder builder)
39-
=> builder.WithImage(TestSession.GetImageFromDockerfile());
38+
protected override ClickHouseBuilder Configure()
39+
=> new ClickHouseBuilder(TestSession.GetImageFromDockerfile());
4040

4141
public override DbProviderFactory DbProviderFactory
4242
=> ClickHouseConnectionFactory.Instance;
@@ -46,8 +46,8 @@ public override DbProviderFactory DbProviderFactory
4646
public class ClickHouseWaitForDatabaseFixture(IMessageSink messageSink)
4747
: ClickHouseDefaultFixture(messageSink)
4848
{
49-
protected override ClickHouseBuilder Configure(ClickHouseBuilder builder)
50-
=> builder.WithImage(TestSession.GetImageFromDockerfile()).WithWaitStrategy(Wait.ForUnixContainer().UntilDatabaseIsAvailable(DbProviderFactory));
49+
protected override ClickHouseBuilder Configure()
50+
=> base.Configure().WithWaitStrategy(Wait.ForUnixContainer().UntilDatabaseIsAvailable(DbProviderFactory));
5151
}
5252

5353
[UsedImplicitly]

tests/Testcontainers.CockroachDb.Tests/CockroachDbContainerTest.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ public async Task ExecScriptReturnsSuccessful()
3535
public class CockroachDbDefaultFixture(IMessageSink messageSink)
3636
: DbContainerFixture<CockroachDbBuilder, CockroachDbContainer>(messageSink)
3737
{
38-
protected override CockroachDbBuilder Configure(CockroachDbBuilder builder)
39-
=> builder.WithImage(TestSession.GetImageFromDockerfile());
38+
protected override CockroachDbBuilder Configure()
39+
=> new CockroachDbBuilder(TestSession.GetImageFromDockerfile());
4040

4141
public override DbProviderFactory DbProviderFactory
4242
=> NpgsqlFactory.Instance;
@@ -46,8 +46,8 @@ public override DbProviderFactory DbProviderFactory
4646
public class CockroachDbWaitForDatabaseFixture(IMessageSink messageSink)
4747
: CockroachDbDefaultFixture(messageSink)
4848
{
49-
protected override CockroachDbBuilder Configure(CockroachDbBuilder builder)
50-
=> builder.WithImage(TestSession.GetImageFromDockerfile()).WithWaitStrategy(Wait.ForUnixContainer().UntilDatabaseIsAvailable(DbProviderFactory));
49+
protected override CockroachDbBuilder Configure()
50+
=> base.Configure().WithWaitStrategy(Wait.ForUnixContainer().UntilDatabaseIsAvailable(DbProviderFactory));
5151
}
5252

5353
[UsedImplicitly]

tests/Testcontainers.Db2.Tests/Db2ContainerTest.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,16 @@ public class Db2DefaultFixture(IMessageSink messageSink)
4040
public override DbProviderFactory DbProviderFactory
4141
=> DB2Factory.Instance;
4242

43-
protected override Db2Builder Configure(Db2Builder builder)
44-
=> builder.WithImage(TestSession.GetImageFromDockerfile()).WithAcceptLicenseAgreement(true);
43+
protected override Db2Builder Configure()
44+
=> new Db2Builder(TestSession.GetImageFromDockerfile()).WithAcceptLicenseAgreement(true);
4545
}
4646

4747
[UsedImplicitly]
4848
public class Db2WaitForDatabaseFixture(IMessageSink messageSink)
4949
: Db2DefaultFixture(messageSink)
5050
{
51-
protected override Db2Builder Configure(Db2Builder builder)
52-
=> base.Configure(builder).WithImage(TestSession.GetImageFromDockerfile()).WithWaitStrategy(Wait.ForUnixContainer().UntilDatabaseIsAvailable(DbProviderFactory));
51+
protected override Db2Builder Configure()
52+
=> base.Configure().WithWaitStrategy(Wait.ForUnixContainer().UntilDatabaseIsAvailable(DbProviderFactory));
5353
}
5454

5555
[UsedImplicitly]

tests/Testcontainers.FirebirdSql.Tests/FirebirdSqlContainerTest.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ public async Task ExecScriptReturnsSuccessful()
3535
public class FirebirdSqlDefaultFixture(IMessageSink messageSink)
3636
: DbContainerFixture<FirebirdSqlBuilder, FirebirdSqlContainer>(messageSink)
3737
{
38-
protected override FirebirdSqlBuilder Configure(FirebirdSqlBuilder builder)
39-
=> builder.WithImage(TestSession.GetImageFromDockerfile());
38+
protected override FirebirdSqlBuilder Configure()
39+
=> new FirebirdSqlBuilder(TestSession.GetImageFromDockerfile());
4040

4141
public override DbProviderFactory DbProviderFactory
4242
=> FirebirdClientFactory.Instance;
@@ -46,40 +46,40 @@ public override DbProviderFactory DbProviderFactory
4646
public class FirebirdSqlWaitForDatabaseFixture(IMessageSink messageSink)
4747
: FirebirdSqlDefaultFixture(messageSink)
4848
{
49-
protected override FirebirdSqlBuilder Configure(FirebirdSqlBuilder builder)
50-
=> builder.WithImage(TestSession.GetImageFromDockerfile()).WithWaitStrategy(Wait.ForUnixContainer().UntilDatabaseIsAvailable(DbProviderFactory));
49+
protected override FirebirdSqlBuilder Configure()
50+
=> base.Configure().WithWaitStrategy(Wait.ForUnixContainer().UntilDatabaseIsAvailable(DbProviderFactory));
5151
}
5252

5353
[UsedImplicitly]
5454
public class FirebirdSql25ScFixture(IMessageSink messageSink)
5555
: FirebirdSqlDefaultFixture(messageSink)
5656
{
57-
protected override FirebirdSqlBuilder Configure(FirebirdSqlBuilder builder)
58-
=> builder.WithImage(TestSession.GetImageFromDockerfile(stage: "fb2.5-sc"));
57+
protected override FirebirdSqlBuilder Configure()
58+
=> new FirebirdSqlBuilder(TestSession.GetImageFromDockerfile(stage: "fb2.5-sc"));
5959
}
6060

6161
[UsedImplicitly]
6262
public class FirebirdSql25SsFixture(IMessageSink messageSink)
6363
: FirebirdSqlDefaultFixture(messageSink)
6464
{
65-
protected override FirebirdSqlBuilder Configure(FirebirdSqlBuilder builder)
66-
=> builder.WithImage(TestSession.GetImageFromDockerfile(stage: "fb2.5-ss"));
65+
protected override FirebirdSqlBuilder Configure()
66+
=> new FirebirdSqlBuilder(TestSession.GetImageFromDockerfile(stage: "fb2.5-ss"));
6767
}
6868

6969
[UsedImplicitly]
7070
public class FirebirdSql30Fixture(IMessageSink messageSink)
7171
: FirebirdSqlDefaultFixture(messageSink)
7272
{
73-
protected override FirebirdSqlBuilder Configure(FirebirdSqlBuilder builder)
74-
=> builder.WithImage(TestSession.GetImageFromDockerfile(stage: "fb3.0"));
73+
protected override FirebirdSqlBuilder Configure()
74+
=> new FirebirdSqlBuilder(TestSession.GetImageFromDockerfile(stage: "fb3.0"));
7575
}
7676

7777
[UsedImplicitly]
7878
public class FirebirdSqlSysdbaFixture(IMessageSink messageSink)
7979
: FirebirdSqlDefaultFixture(messageSink)
8080
{
81-
protected override FirebirdSqlBuilder Configure(FirebirdSqlBuilder builder)
82-
=> builder.WithImage(TestSession.GetImageFromDockerfile()).WithUsername("sysdba").WithPassword("some-password");
81+
protected override FirebirdSqlBuilder Configure()
82+
=> base.Configure().WithUsername("sysdba").WithPassword("some-password");
8383
}
8484

8585
[UsedImplicitly]

0 commit comments

Comments
 (0)