-
-
Notifications
You must be signed in to change notification settings - Fork 545
Expand file tree
/
Copy pathTestWebApplicationFactory.cs
More file actions
101 lines (85 loc) · 3.69 KB
/
TestWebApplicationFactory.cs
File metadata and controls
101 lines (85 loc) · 3.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
using Core.Events;
using Core.Events.External;
using Core.Requests;
using FluentAssertions;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Open.ChannelExtensions;
using Polly;
namespace Core.Testing;
public class TestWebApplicationFactory<TProject>: WebApplicationFactory<TProject> where TProject : class
{
private readonly DummyExternalEventProducer externalEventProducer = new();
private readonly DummyExternalCommandBus externalCommandBus = new();
private readonly EventListener eventListener = new();
private readonly string schemaName = $"test{Guid.CreateVersion7().ToString("N").ToLower()}";
protected override IHost CreateHost(IHostBuilder builder)
{
builder.ConfigureServices(services =>
{
services
.AddSingleton<IExternalEventProducer>(externalEventProducer)
.AddSingleton<IEventBus>(sp =>
new EventCatcher(
eventListener,
new EventBusDecoratorWithExternalProducer(sp.GetRequiredService<EventBus>(),
sp.GetRequiredService<IExternalEventProducer>())
)
)
.AddSingleton(eventListener)
.AddSingleton<IExternalCommandBus>(externalCommandBus)
.AddSingleton<IExternalEventConsumer, DummyExternalEventConsumer>();
});
Environment.SetEnvironmentVariable("ConnectionStrings__kafka", "localhost:9092");
Environment.SetEnvironmentVariable("SchemaName", schemaName);
return Policy.Handle<Exception>()
.WaitAndRetry(5, _ => TimeSpan.FromMilliseconds(500))
.Execute(() => base.CreateHost(builder));
}
public void PublishedExternalEventsOfType<TEvent>() where TEvent : IExternalEvent =>
externalEventProducer.PublishedEvents.OfType<TEvent>().Should().NotBeEmpty();
public Task PublishInternalEvent<TEvent>(TEvent @event, CancellationToken ct = default) where TEvent : notnull =>
PublishInternalEvent(
new EventEnvelope<TEvent>(@event, new EventMetadata(Guid.CreateVersion7().ToString(), 0, 0, null)), ct);
public async Task PublishInternalEvent<TEvent>(EventEnvelope<TEvent> eventEnvelope, CancellationToken ct = default)
where TEvent : notnull
{
using var scope = Services.CreateScope();
var eventBus = scope.ServiceProvider.GetRequiredService<IEventBus>();
await eventBus.Publish(eventEnvelope, ct).ConfigureAwait(false);
}
public IAsyncEnumerable<TEvent> PublishedInternalEventsOfType<TEvent>(
CancellationToken ct = default
) =>
PublishedInternalEventsOfType((TEvent _) => true, ct);
public IAsyncEnumerable<TEvent> PublishedInternalEventsOfType<TEvent>(
Func<TEvent, bool> predicate,
CancellationToken ct = default
) =>
eventListener.Reader
.Filter(x => x is TEvent)
.Transform(x => (TEvent)x)
.Filter(predicate)
.ReadAllAsync(ct);
public async Task ShouldPublishInternalEventOfType<TEvent>(
Func<TEvent, bool> predicate,
long timeout = 5000
)
{
try
{
var cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromMilliseconds(timeout));
await foreach (var _ in PublishedInternalEventsOfType(predicate, cts.Token).ConfigureAwait(false))
{
return;
}
}
catch (OperationCanceledException)
{
0.Should().Be(1, "No events matching criteria were published");
}
}
}