Skip to content

Commit

Permalink
add a bunch of abstract test classes targeting domain behaviour
Browse files Browse the repository at this point in the history
  • Loading branch information
corstian committed May 29, 2024
1 parent 7acb9f1 commit c7dfcbc
Show file tree
Hide file tree
Showing 10 changed files with 329 additions and 0 deletions.
1 change: 1 addition & 0 deletions tests/Skyhop.Domain.Tests/Skyhop.Domain.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

<ItemGroup>
<ProjectReference Include="..\..\samples\Skyhop.Domain\Skyhop.Domain.csproj" />
<ProjectReference Include="..\Whaally.Domain.Tests\Whaally.Domain.Tests.csproj" />
</ItemGroup>

</Project>
28 changes: 28 additions & 0 deletions tests/Skyhop.Domain.Tests/SkyhopCommandTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using FluentAssertions;
using Whaally.Domain.Abstractions.Aggregate;
using Whaally.Domain.Abstractions.Command;
using Whaally.Domain.Tests;

namespace Skyhop.Domain.Tests;

public abstract class SkyhopCommandTest<TAggregate, TCommand> : CommandTest<TAggregate, TCommand>
where TAggregate : class, IAggregate, new()
where TCommand : class, ICommand
{
public SkyhopCommandTest(
ICommandHandler<TAggregate, TCommand> handler,
TAggregate aggregate,
TCommand command) : base(handler, aggregate, command) { }

[Fact]
public void AssertCommandSerializerIsGenerated()
{
typeof(TCommand).Should().BeDecoratedWith<GenerateSerializerAttribute>();
}

[Fact]
public void AssertCommandIsMarkedImmutable()
{
typeof(TCommand).Should().BeDecoratedWith<ImmutableAttribute>();
}
}
28 changes: 28 additions & 0 deletions tests/Skyhop.Domain.Tests/SkyhopEventTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using FluentAssertions;
using Whaally.Domain.Abstractions.Aggregate;
using Whaally.Domain.Abstractions.Event;
using Whaally.Domain.Tests;

namespace Skyhop.Domain.Tests;

public abstract class SkyhopEventTest<TAggregate, TEvent> : EventTest<TAggregate, TEvent>
where TAggregate : class, IAggregate, new()
where TEvent : class, IEvent
{
public SkyhopEventTest(
IEventHandler<TAggregate, TEvent> handler,
TAggregate aggregate,
TEvent @event) : base(handler, aggregate, @event) { }

[Fact]
public void AssertCommandSerializerIsGenerated()
{
typeof(TEvent).Should().BeDecoratedWith<GenerateSerializerAttribute>();
}

[Fact]
public void AssertCommandIsMarkedImmutable()
{
typeof(TEvent).Should().BeDecoratedWith<ImmutableAttribute>();
}
}
15 changes: 15 additions & 0 deletions tests/Skyhop.Domain.Tests/SkyhopSagaTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Whaally.Domain.Abstractions.Event;
using Whaally.Domain.Abstractions.Saga;
using Whaally.Domain.Tests;

namespace Skyhop.Domain.Tests;

public abstract class SkyhopSagaTest<TEvent> : SagaTest<TEvent>
where TEvent : class, IEvent
{
protected SkyhopSagaTest(
ISaga<TEvent> saga,
TEvent @event) : base(saga, @event) { }

// ToDo: dobuble check if a saga implemented on Orleans requires any attributes
}
25 changes: 25 additions & 0 deletions tests/Skyhop.Domain.Tests/SkyhopServiceTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using FluentAssertions;
using Whaally.Domain.Abstractions.Service;
using Whaally.Domain.Tests;

namespace Skyhop.Domain.Tests;

public abstract class SkyhopServiceTest<TService> : ServiceTest<TService>
where TService : class, IService
{
public SkyhopServiceTest(
IServiceHandler<TService> handler,
TService service) : base(handler, service) { }

[Fact]
public void AssertCommandSerializerIsGenerated()
{
typeof(TService).Should().BeDecoratedWith<GenerateSerializerAttribute>();
}

[Fact]
public void AssertCommandIsMarkedImmutable()
{
typeof(TService).Should().BeDecoratedWith<ImmutableAttribute>();
}
}
62 changes: 62 additions & 0 deletions tests/Whaally.Domain.Tests/CommandTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using FluentAssertions;
using FluentResults;
using Whaally.Domain.Abstractions.Aggregate;
using Whaally.Domain.Abstractions.Command;
using Whaally.Domain.Abstractions.Event;
using Whaally.Domain.Command;

namespace Whaally.Domain.Tests;

public abstract class CommandTest<TAggregate, TCommand> : DomainTest
where TAggregate : class, IAggregate, new()
where TCommand : class, ICommand
{
public ICommandHandler<TAggregate, TCommand> Handler { get; }
public TAggregate Aggregate { get; }
public TCommand Command { get; }

public CommandHandlerContext<TAggregate> Context { get; }
public Result Result { get; private init; }
public IEnumerable<IEvent> Events { get; private init; }

public CommandTest(
ICommandHandler<TAggregate, TCommand> handler,
TAggregate aggregate,
TCommand command)
{
Handler = handler;
Aggregate = aggregate;
Command = command;

var id = Guid.NewGuid();
Context = new CommandHandlerContext<TAggregate>(id.ToString())
{
Activity = default,
Aggregate = Aggregate
};

var output = Handler.Evaluate(Context, Command);

if (output.GetType().GenericTypeArguments.Any())
Result = new Result().WithReasons(output.Reasons);
else
Result = (Result)output;

Events = Context.Events.Select(q => q.Message);
}

[Fact]
public void UponFailureAssertNoEvents()
{
if (Result.IsFailed)
{
Events.Should().BeEmpty();
}
}

[Fact]
public void AssertResultDoesNotContainObject()
{
Result.GetType().Should().NotBeOfType(typeof(IResult<>));
}
}
19 changes: 19 additions & 0 deletions tests/Whaally.Domain.Tests/DomainTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Microsoft.Extensions.DependencyInjection;
using Whaally.Domain.Abstractions.Aggregate;

namespace Whaally.Domain.Tests;

public abstract class DomainTest : IDisposable
{
public IServiceProvider Services = new ServiceCollection()
.AddDomain()
.BuildServiceProvider();

public Whaally.Domain.Domain Domain => Services.GetRequiredService<Whaally.Domain.Domain>();
public IAggregateHandlerFactory Factory => Services.GetRequiredService<IAggregateHandlerFactory>();

public void Dispose()
{

}
}
37 changes: 37 additions & 0 deletions tests/Whaally.Domain.Tests/EventTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using FluentAssertions;
using Whaally.Domain.Abstractions.Aggregate;
using Whaally.Domain.Abstractions.Event;
using Whaally.Domain.Event;

namespace Whaally.Domain.Tests;

public abstract class EventTest<TAggregate, TEvent> : DomainTest
where TAggregate : class, IAggregate, new()
where TEvent : class, IEvent
{
public IEventHandler<TAggregate, TEvent> Handler { get; }
public TAggregate Aggregate { get; }
public TEvent Event { get; }

public EventHandlerContext<TAggregate> Context { get; }
public TAggregate UpdatedAggregate { get; }

public EventTest(
IEventHandler<TAggregate, TEvent> handler,
TAggregate aggregate,
TEvent @event)
{
Handler = handler;
Aggregate = aggregate;
Event = @event;

var id = Guid.NewGuid();
Context = new EventHandlerContext<TAggregate>(id.ToString())
{
Activity = default,
Aggregate = Aggregate
};

UpdatedAggregate = Handler.Apply(Context, Event);
}
}
57 changes: 57 additions & 0 deletions tests/Whaally.Domain.Tests/SagaTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using FluentAssertions;
using FluentResults;
using Whaally.Domain.Abstractions.Command;
using Whaally.Domain.Abstractions.Event;
using Whaally.Domain.Abstractions.Saga;
using Whaally.Domain.Saga;

namespace Whaally.Domain.Tests;

public abstract class SagaTest<TEvent> : DomainTest
where TEvent : class, IEvent
{
public ISaga<TEvent> Saga { get; }
public TEvent Event { get; }

public SagaContext Context { get; }
public Result Result { get; }
public IEnumerable<ICommand> Commands { get; }

public SagaTest(
ISaga<TEvent> saga,
TEvent @event)
{
Saga = saga;
Event = @event;

// ToDo: Provide IServiceProvider
Context = new SagaContext(default!)
{
Activity = default
};

var output = Saga.Evaluate(Context, Event).Result;

if (output.GetType().GenericTypeArguments.Any())
Result = new Result().WithReasons(output.Reasons);
else
Result = (Result)output;

Commands = Context.Commands.Select(q => q.Message);
}

[Fact]
public void UponFailureAssertNoCommands()
{
if (Result.IsFailed)
{
Commands.Should().BeEmpty();
}
}

[Fact]
public void AssertResultDoesNotContainObject()
{
Result.GetType().Should().NotBeOfType(typeof(IResult<>));
}
}
57 changes: 57 additions & 0 deletions tests/Whaally.Domain.Tests/ServiceTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using FluentAssertions;
using FluentResults;
using Whaally.Domain.Abstractions.Command;
using Whaally.Domain.Abstractions.Service;
using Whaally.Domain.Service;

namespace Whaally.Domain.Tests;

public abstract class ServiceTest<TService> : DomainTest
where TService : class, IService
{
public IServiceHandler<TService> Handler { get; }
public TService Service { get; }

public ServiceHandlerContext Context { get; }
public Result Result { get; private init; }
public IEnumerable<ICommand> Commands { get; private init; }

public ServiceTest(
IServiceHandler<TService> handler,
TService service)
{
Handler = handler;
Service = service;

var id = Guid.NewGuid();
// ToDo: Provide IServiceProvider
Context = new ServiceHandlerContext(default!)
{
Activity = default
};

var output = Handler.Handle(Context, Service).Result;

if (output.GetType().GenericTypeArguments.Any())
Result = new Result().WithReasons(output.Reasons);
else
Result = (Result)output;

Commands = Context.Commands.Select(q => q.Message);
}

[Fact]
public void UponFailureAssertNoCommands()
{
if (Result.IsFailed)
{
Commands.Should().BeEmpty();
}
}

[Fact]
public void AssertResultDoesNotContainObject()
{
Result.GetType().Should().NotBeOfType(typeof(IResult<>));
}
}

0 comments on commit c7dfcbc

Please sign in to comment.