Skip to content

Commit c20188e

Browse files
committed
Share the lifetime implementation between ContainerFixture and ContainerTest
1 parent e419240 commit c20188e

File tree

3 files changed

+72
-69
lines changed

3 files changed

+72
-69
lines changed

src/Testcontainers.Xunit/ContainerFixture.cs

Lines changed: 3 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -8,61 +8,14 @@ namespace Testcontainers.Xunit;
88
/// <typeparam name="TBuilderEntity">The builder entity.</typeparam>
99
/// <typeparam name="TContainerEntity">The container entity.</typeparam>
1010
[PublicAPI]
11-
public class ContainerFixture<TBuilderEntity, TContainerEntity> : IAsyncLifetime
11+
public class ContainerFixture<TBuilderEntity, TContainerEntity>(IMessageSink messageSink) : ContainerLifetime<TBuilderEntity, TContainerEntity>
1212
where TBuilderEntity : IContainerBuilder<TBuilderEntity, TContainerEntity>, new()
1313
where TContainerEntity : IContainer
1414
{
15-
private Lazy<TContainerEntity> _container;
16-
17-
public ContainerFixture(IMessageSink messageSink)
18-
{
19-
MessageSink = messageSink;
20-
_container = new Lazy<TContainerEntity>(() =>
21-
{
22-
var containerBuilder = new TBuilderEntity().WithLogger(new MessageSinkLogger(MessageSink));
23-
return Configure(containerBuilder).Build();
24-
});
25-
}
26-
2715
/// <summary>
2816
/// The message sink used for reporting diagnostic messages.
2917
/// </summary>
30-
protected IMessageSink MessageSink { get; }
31-
32-
/// <summary>
33-
/// The container instance.
34-
/// </summary>
35-
public TContainerEntity Container => _container.Value;
36-
37-
/// <summary>
38-
/// Extension point to further configure the container instance.
39-
/// </summary>
40-
/// <example>
41-
/// <code>
42-
/// public class MariaDbRootUserFixture(IMessageSink messageSink) : DbContainerFixture&lt;MariaDbBuilder, MariaDbContainer&gt;(messageSink)
43-
/// {
44-
/// public override DbProviderFactory DbProviderFactory => MySqlConnectorFactory.Instance;
45-
///
46-
/// protected override MariaDbBuilder Configure(MariaDbBuilder builder)
47-
/// {
48-
/// return builder.WithUsername("root");
49-
/// }
50-
/// }
51-
/// </code>
52-
/// </example>
53-
/// <param name="builder">The container builder.</param>
54-
/// <returns>A configured instance of <typeparamref name="TBuilderEntity" />.</returns>
55-
protected virtual TBuilderEntity Configure(TBuilderEntity builder) => builder;
56-
57-
/// <inheritdoc />
58-
Task IAsyncLifetime.InitializeAsync() => InitializeAsync();
59-
60-
/// <inheritdoc cref="IAsyncLifetime.InitializeAsync()" />
61-
protected virtual Task InitializeAsync() => Container.StartAsync();
62-
63-
/// <inheritdoc />
64-
Task IAsyncLifetime.DisposeAsync() => DisposeAsync();
18+
protected IMessageSink MessageSink { get; } = messageSink;
6519

66-
/// <inheritdoc cref="IAsyncLifetime.DisposeAsync()" />
67-
protected virtual Task DisposeAsync() => Container.DisposeAsync().AsTask();
20+
protected override ILogger Logger { get; } = new MessageSinkLogger(messageSink);
6821
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
namespace Testcontainers.Xunit;
2+
3+
/// <summary>
4+
/// Base class managing the lifetime of a container.
5+
/// </summary>
6+
/// <typeparam name="TBuilderEntity">The builder entity.</typeparam>
7+
/// <typeparam name="TContainerEntity">The container entity.</typeparam>
8+
public abstract class ContainerLifetime<TBuilderEntity, TContainerEntity> : IAsyncLifetime
9+
where TBuilderEntity : IContainerBuilder<TBuilderEntity, TContainerEntity>, new()
10+
where TContainerEntity : IContainer
11+
{
12+
private readonly Lazy<TContainerEntity> _container;
13+
14+
/// <summary>
15+
/// The logger.
16+
/// </summary>
17+
protected abstract ILogger Logger { get; }
18+
19+
protected ContainerLifetime()
20+
{
21+
_container = new Lazy<TContainerEntity>(() =>
22+
{
23+
var containerBuilder = new TBuilderEntity().WithLogger(Logger);
24+
return Configure(containerBuilder).Build();
25+
});
26+
}
27+
28+
/// <summary>
29+
/// Extension point to further configure the container instance.
30+
/// </summary>
31+
/// <example>
32+
/// <code>
33+
/// public class MariaDbRootUserFixture(IMessageSink messageSink) : DbContainerFixture&lt;MariaDbBuilder, MariaDbContainer&gt;(messageSink)
34+
/// {
35+
/// public override DbProviderFactory DbProviderFactory =&gt; MySqlConnectorFactory.Instance;
36+
/// <br />
37+
/// protected override MariaDbBuilder Configure(MariaDbBuilder builder)
38+
/// {
39+
/// return builder.WithUsername("root");
40+
/// }
41+
/// }
42+
/// </code>
43+
/// </example>
44+
/// <param name="builder">The container builder.</param>
45+
/// <returns>A configured instance of <typeparamref name="TBuilderEntity" />.</returns>
46+
protected virtual TBuilderEntity Configure(TBuilderEntity builder) => builder;
47+
48+
/// <summary>
49+
/// The container instance.
50+
/// </summary>
51+
public TContainerEntity Container => _container.Value;
52+
53+
/// <inheritdoc />
54+
Task IAsyncLifetime.InitializeAsync() => InitializeAsync();
55+
56+
/// <inheritdoc cref="IAsyncLifetime.InitializeAsync()" />
57+
protected virtual Task InitializeAsync() => Container.StartAsync();
58+
59+
/// <inheritdoc />
60+
Task IAsyncLifetime.DisposeAsync() => DisposeAsync();
61+
62+
/// <inheritdoc cref="IAsyncLifetime.DisposeAsync()" />
63+
protected virtual Task DisposeAsync() => Container.DisposeAsync().AsTask();
64+
}

src/Testcontainers.Xunit/ContainerTest.cs

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,16 @@ 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 ContainerTest<TBuilderEntity, TContainerEntity> : IAsyncLifetime
10+
public abstract class ContainerTest<TBuilderEntity, TContainerEntity>(ITestOutputHelper testOutputHelper, Func<TBuilderEntity, TBuilderEntity> configure = null) : ContainerLifetime<TBuilderEntity, TContainerEntity>
1111
where TBuilderEntity : IContainerBuilder<TBuilderEntity, TContainerEntity>, new()
1212
where TContainerEntity : IContainer
1313
{
14-
protected ContainerTest(ITestOutputHelper testOutputHelper, Func<TBuilderEntity, TBuilderEntity> configure = null)
15-
{
16-
var builder = new TBuilderEntity().WithLogger(new TestOutputLogger(testOutputHelper));
17-
Container = configure == null ? builder.Build() : configure(builder).Build();
18-
}
19-
2014
/// <summary>
21-
/// The container instance.
15+
/// The helper used for writing messages to the test output.
2216
/// </summary>
23-
protected TContainerEntity Container { get; }
24-
25-
/// <inheritdoc />
26-
Task IAsyncLifetime.InitializeAsync() => InitializeAsync();
27-
28-
/// <inheritdoc cref="IAsyncLifetime.InitializeAsync()" />
29-
protected virtual Task InitializeAsync() => Container.StartAsync();
17+
protected ITestOutputHelper TestOutputHelper { get; } = testOutputHelper;
3018

31-
/// <inheritdoc />
32-
Task IAsyncLifetime.DisposeAsync() => DisposeAsync();
19+
protected override ILogger Logger { get; } = new TestOutputLogger(testOutputHelper);
3320

34-
/// <inheritdoc cref="IAsyncLifetime.DisposeAsync()" />
35-
protected virtual Task DisposeAsync() => Container.DisposeAsync().AsTask();
21+
protected override TBuilderEntity Configure(TBuilderEntity builder) => configure != null ? configure(builder) : builder;
3622
}

0 commit comments

Comments
 (0)