From d65c77265e58c3fb786b56f62bc517a5a18c1042 Mon Sep 17 00:00:00 2001 From: Oskar Dudycz Date: Thu, 19 Oct 2023 14:50:54 +0200 Subject: [PATCH] Adjusted Async projection test with IoC injection to remove flakiness --- docs/events/projections/ioc.md | 17 ++++++----- .../projections_with_IoC_services.cs | 28 +++++++++---------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/docs/events/projections/ioc.md b/docs/events/projections/ioc.md index 97bb97412df..a917a65bfb4 100644 --- a/docs/events/projections/ioc.md +++ b/docs/events/projections/ioc.md @@ -16,7 +16,7 @@ Let's say you have a custom aggregation projection like this one below that need ```cs -public class ProductProjection : CustomProjection +public class ProductProjection: CustomProjection { private readonly IPriceLookup _lookup; @@ -28,10 +28,14 @@ public class ProductProjection : CustomProjection ProjectionName = "Product"; } - public override ValueTask ApplyChangesAsync(DocumentSessionBase session, EventSlice slice, CancellationToken cancellation, - ProjectionLifecycle lifecycle = ProjectionLifecycle.Inline) + public override ValueTask ApplyChangesAsync( + DocumentSessionBase session, + EventSlice slice, + CancellationToken cancellation, + ProjectionLifecycle lifecycle = ProjectionLifecycle.Inline + ) { - slice.Aggregate ??= new Product{Id = slice.Id}; + slice.Aggregate ??= new Product { Id = slice.Id }; foreach (var data in slice.AllData()) { @@ -52,7 +56,7 @@ public class ProductProjection : CustomProjection } } ``` -snippet source | anchor +snippet source | anchor Now, we *want* to use this projection at runtime within Marten, and need to register the projection @@ -74,11 +78,10 @@ using var host = await Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder() }) // Note that this is chained after the call to AddMarten() .AddProjectionWithServices(ProjectionLifecycle.Inline, ServiceLifetime.Singleton); - }) .StartAsync(); ``` -snippet source | anchor +snippet source | anchor Note that we're having to explicitly specify the projection lifecycle for the projection used within diff --git a/src/EventSourcingTests/Projections/projections_with_IoC_services.cs b/src/EventSourcingTests/Projections/projections_with_IoC_services.cs index 932cb07cc7f..08c05e0cd29 100644 --- a/src/EventSourcingTests/Projections/projections_with_IoC_services.cs +++ b/src/EventSourcingTests/Projections/projections_with_IoC_services.cs @@ -17,7 +17,6 @@ namespace EventSourcingTests.Projections; - [Collection("ioc")] public class projections_with_IoC_services { @@ -38,7 +37,6 @@ public async Task use_projection_as_singleton_and_inline() }) // Note that this is chained after the call to AddMarten() .AddProjectionWithServices(ProjectionLifecycle.Inline, ServiceLifetime.Singleton); - }) .StartAsync(); @@ -46,14 +44,13 @@ public async Task use_projection_as_singleton_and_inline() var store = host.Services.GetRequiredService(); - using var session = store.LightweightSession(); + await using var session = store.LightweightSession(); var streamId = session.Events.StartStream(new ProductRegistered("Ankle Socks", "Socks")).Id; await session.SaveChangesAsync(); var product = await session.LoadAsync(streamId); product.Price.ShouldBeGreaterThan(0); product.Name.ShouldBe("Ankle Socks"); - } [Fact] @@ -68,16 +65,16 @@ public async Task use_projection_as_singleton_and_async() { opts.Connection(ConnectionSource.ConnectionString); opts.DatabaseSchemaName = "ioc"; + opts.Projections.DaemonLockId = 99123; }) .AddAsyncDaemon(DaemonMode.Solo) .AddProjectionWithServices(ProjectionLifecycle.Async, ServiceLifetime.Singleton); - }).StartAsync(); var store = host.Services.GetRequiredService(); await store.Advanced.Clean.CompletelyRemoveAllAsync(); - using var session = store.LightweightSession(); + await using var session = store.LightweightSession(); var streamId = session.Events.StartStream(new ProductRegistered("Ankle Socks", "Socks")).Id; await session.SaveChangesAsync(); @@ -87,9 +84,9 @@ public async Task use_projection_as_singleton_and_async() await daemon.Tracker.WaitForShardState("Product:All", 1); var product = await session.LoadAsync(streamId); + product.ShouldNotBeNull(); product.Price.ShouldBeGreaterThan(0); product.Name.ShouldBe("Ankle Socks"); - } [Fact] @@ -105,23 +102,20 @@ public async Task use_projection_as_scoped_and_inline() opts.Connection(ConnectionSource.ConnectionString); opts.DatabaseSchemaName = "ioc"; }).AddProjectionWithServices(ProjectionLifecycle.Inline, ServiceLifetime.Scoped); - }).StartAsync(); var store = host.Services.GetRequiredService(); - using var session = store.LightweightSession(); + await using var session = store.LightweightSession(); var streamId = session.Events.StartStream(new ProductRegistered("Ankle Socks", "Socks")).Id; await session.SaveChangesAsync(); var product = await session.LoadAsync(streamId); product.Price.ShouldBeGreaterThan(0); product.Name.ShouldBe("Ankle Socks"); - } } - public interface IPriceLookup { double PriceFor(string category); @@ -148,7 +142,7 @@ public record ProductRegistered(string Name, string Category); #region sample_ProductProjection -public class ProductProjection : CustomProjection +public class ProductProjection: CustomProjection { private readonly IPriceLookup _lookup; @@ -160,10 +154,14 @@ public ProductProjection(IPriceLookup lookup) ProjectionName = "Product"; } - public override ValueTask ApplyChangesAsync(DocumentSessionBase session, EventSlice slice, CancellationToken cancellation, - ProjectionLifecycle lifecycle = ProjectionLifecycle.Inline) + public override ValueTask ApplyChangesAsync( + DocumentSessionBase session, + EventSlice slice, + CancellationToken cancellation, + ProjectionLifecycle lifecycle = ProjectionLifecycle.Inline + ) { - slice.Aggregate ??= new Product{Id = slice.Id}; + slice.Aggregate ??= new Product { Id = slice.Id }; foreach (var data in slice.AllData()) {