Add integration test project with MediatR procedure tests

Added ReC.Tests project with integration tests for stored procedure commands and queries via MediatR, covering endpoints, actions, results, and profiles. Introduced a test base for DI/configuration, helper for private property access, and updated the solution to include the new test suite. Tests use NUnit and cover both positive and negative scenarios.
This commit is contained in:
2026-01-16 15:24:51 +01:00
parent df665e3b98
commit ce35ef588f
14 changed files with 693 additions and 0 deletions

View File

@@ -26,6 +26,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "presentation", "presentatio
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "core", "core", "{2CEF945E-94D6-4273-9BE1-20B628CD0A57}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{8353C9B1-CC4A-4097-A936-C06D4C618415}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReC.Tests", "tests\ReC.Tests\ReC.Tests.csproj", "{457ED5AC-F4A0-41C3-9758-4A3C272EDC11}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -52,6 +56,10 @@ Global
{DA3A6BDD-8045-478F-860B-D1F0EB97F02B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DA3A6BDD-8045-478F-860B-D1F0EB97F02B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DA3A6BDD-8045-478F-860B-D1F0EB97F02B}.Release|Any CPU.Build.0 = Release|Any CPU
{457ED5AC-F4A0-41C3-9758-4A3C272EDC11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{457ED5AC-F4A0-41C3-9758-4A3C272EDC11}.Debug|Any CPU.Build.0 = Debug|Any CPU
{457ED5AC-F4A0-41C3-9758-4A3C272EDC11}.Release|Any CPU.ActiveCfg = Release|Any CPU
{457ED5AC-F4A0-41C3-9758-4A3C272EDC11}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -65,6 +73,7 @@ Global
{3F88DACC-CEC0-4D9A-8BAA-37F67B02DC04} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{3D6EF9B9-D00D-432A-8477-067902B5CE8E} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{2CEF945E-94D6-4273-9BE1-20B628CD0A57} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{457ED5AC-F4A0-41C3-9758-4A3C272EDC11} = {8353C9B1-CC4A-4097-A936-C06D4C618415}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F7B09104-4072-4635-9492-9C7C68D96ABD}

View File

@@ -0,0 +1,61 @@
using System.Threading.Tasks;
using MediatR;
using Microsoft.Extensions.DependencyInjection;
using NUnit.Framework;
using ReC.Application.Common.Procedures.DeleteProcedure;
using ReC.Application.Common.Procedures.InsertProcedure;
using ReC.Application.Common.Procedures.UpdateProcedure;
using ReC.Application.EndpointAuth.Commands;
using ReC.Tests.Application;
namespace ReC.Tests.Application.EndpointAuth;
[TestFixture]
public class EndpointAuthProcedureTests : RecApplicationTestBase
{
private (ISender Sender, IServiceScope Scope) CreateScopedSender()
{
var scope = ServiceProvider.CreateScope();
var sender = scope.ServiceProvider.GetRequiredService<ISender>();
return (sender, scope);
}
[Test]
public async Task InsertEndpointAuthProcedure_runs_via_mediator()
{
var procedure = new InsertEndpointAuthProcedure { Active = true, Description = "auth", TypeId = 1, ApiKey = "key", ApiValue = "value" };
var objectProc = procedure.ToObjectProcedure("ReC.Tests");
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
Assert.That(result, Is.GreaterThan(0));
}
[Test]
public async Task UpdateEndpointAuthProcedure_runs_via_mediator()
{
var procedure = new UpdateEndpointAuthProcedure { Active = false, Description = "auth-update", TypeId = 2 };
var objectProc = procedure.ToObjectProcedure(15, "ReC.Tests");
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
Assert.That(result, Is.EqualTo(0));
}
[Test]
public async Task DeleteEndpointAuthProcedure_runs_via_mediator()
{
var procedure = new DeleteEndpointAuthProcedure { Start = 3, End = 4, Force = false };
var objectProc = procedure.ToObjectProcedure();
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
Assert.That(result, Is.EqualTo(0));
}
}

View File

@@ -0,0 +1,61 @@
using System.Threading.Tasks;
using MediatR;
using Microsoft.Extensions.DependencyInjection;
using NUnit.Framework;
using ReC.Application.Common.Procedures.DeleteProcedure;
using ReC.Application.Common.Procedures.InsertProcedure;
using ReC.Application.Common.Procedures.UpdateProcedure;
using ReC.Application.EndpointParams.Commands;
using ReC.Tests.Application;
namespace ReC.Tests.Application.EndpointParams;
[TestFixture]
public class EndpointParamsProcedureTests : RecApplicationTestBase
{
private (ISender Sender, IServiceScope Scope) CreateScopedSender()
{
var scope = ServiceProvider.CreateScope();
var sender = scope.ServiceProvider.GetRequiredService<ISender>();
return (sender, scope);
}
[Test]
public async Task InsertEndpointParamsProcedure_runs_via_mediator()
{
var procedure = new InsertEndpointParamsProcedure { Active = true, Description = "param", GroupId = 1, Sequence = 1, Key = "k", Value = "v" };
var objectProc = procedure.ToObjectProcedure("ReC.Tests");
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
Assert.That(result, Is.GreaterThan(0));
}
[Test]
public async Task UpdateEndpointParamsProcedure_runs_via_mediator()
{
var procedure = new UpdateEndpointParamsProcedure { Active = false, Description = "param-update", GroupId = 2, Sequence = 2, Key = "k2", Value = "v2" };
var objectProc = procedure.ToObjectProcedure(25, "ReC.Tests");
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
Assert.That(result, Is.EqualTo(0));
}
[Test]
public async Task DeleteEndpointParamsProcedure_runs_via_mediator()
{
var procedure = new DeleteEndpointParamsProcedure { Start = 5, End = 6, Force = true };
var objectProc = procedure.ToObjectProcedure();
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
Assert.That(result, Is.EqualTo(0));
}
}

View File

@@ -0,0 +1,61 @@
using System.Threading.Tasks;
using MediatR;
using Microsoft.Extensions.DependencyInjection;
using NUnit.Framework;
using ReC.Application.Common.Procedures.DeleteProcedure;
using ReC.Application.Common.Procedures.InsertProcedure;
using ReC.Application.Common.Procedures.UpdateProcedure;
using ReC.Application.Endpoints.Commands;
using ReC.Tests.Application;
namespace ReC.Tests.Application.Endpoints;
[TestFixture]
public class EndpointProcedureTests : RecApplicationTestBase
{
private (ISender Sender, IServiceScope Scope) CreateScopedSender()
{
var scope = ServiceProvider.CreateScope();
var sender = scope.ServiceProvider.GetRequiredService<ISender>();
return (sender, scope);
}
[Test]
public async Task InsertEndpointProcedure_runs_via_mediator()
{
var procedure = new InsertEndpointProcedure { Active = true, Description = "desc", Uri = "http://example" };
var objectProc = procedure.ToObjectProcedure("ReC.Tests");
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
Assert.That(result, Is.GreaterThan(0));
}
[Test]
public async Task UpdateEndpointProcedure_runs_via_mediator()
{
var procedure = new UpdateEndpointProcedure { Active = false, Description = "updated", Uri = "http://updated" };
var objectProc = procedure.ToObjectProcedure(12, "ReC.Tests");
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
Assert.That(result, Is.EqualTo(0));
}
[Test]
public async Task DeleteEndpointProcedure_runs_via_mediator()
{
var procedure = new DeleteEndpointProcedure { Start = 1, End = 2, Force = true };
var objectProc = procedure.ToObjectProcedure();
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
Assert.That(result, Is.EqualTo(0));
}
}

View File

@@ -0,0 +1,58 @@
using System.Threading.Tasks;
using MediatR;
using Microsoft.Extensions.DependencyInjection;
using NUnit.Framework;
using ReC.Application.Common.Procedures.DeleteProcedure;
using ReC.Application.Common.Procedures.InsertProcedure;
using ReC.Application.Common.Procedures.UpdateProcedure;
using ReC.Application.Profile.Commands;
using ReC.Tests.Application;
namespace ReC.Tests.Application.Procedures;
[TestFixture]
public class ProcedureExecutionTests : RecApplicationTestBase
{
private (ISender Sender, IServiceScope Scope) CreateScopedSender()
{
var scope = ServiceProvider.CreateScope();
var sender = scope.ServiceProvider.GetRequiredService<ISender>();
return (sender, scope);
}
[Test]
public async Task ExecuteInsertProcedure_runs_with_addedWho()
{
var procedure = new InsertProfileProcedure { Name = "name" };
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.ExecuteInsertProcedure(procedure, "ReC.Tests");
Assert.That(result, Is.GreaterThan(0));
}
[Test]
public async Task ExecuteUpdateProcedure_runs_with_changedWho()
{
var procedure = new UpdateProfileProcedure { Name = "updated" };
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.ExecuteUpdateProcedure(procedure, 123, "ReC.Tests");
Assert.That(result, Is.EqualTo(0));
}
[Test]
public async Task ExecuteDeleteProcedure_runs()
{
var procedure = new DeleteProfileProcedure { Start = 1, End = 2, Force = true };
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.ExecuteDeleteProcedure(procedure);
Assert.That(result, Is.EqualTo(0));
}
}

View File

@@ -0,0 +1,61 @@
using System.Threading.Tasks;
using MediatR;
using Microsoft.Extensions.DependencyInjection;
using NUnit.Framework;
using ReC.Application.Common.Procedures.DeleteProcedure;
using ReC.Application.Common.Procedures.InsertProcedure;
using ReC.Application.Common.Procedures.UpdateProcedure;
using ReC.Application.Profile.Commands;
using ReC.Tests.Application;
namespace ReC.Tests.Application.Profile;
[TestFixture]
public class ProfileProcedureTests : RecApplicationTestBase
{
private (ISender Sender, IServiceScope Scope) CreateScopedSender()
{
var scope = ServiceProvider.CreateScope();
var sender = scope.ServiceProvider.GetRequiredService<ISender>();
return (sender, scope);
}
[Test]
public async Task InsertProfileProcedure_runs_via_mediator()
{
var procedure = new InsertProfileProcedure { Active = true, TypeId = 1, Name = "name", Mandantor = "man" };
var objectProc = procedure.ToObjectProcedure("ReC.Tests");
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
Assert.That(result, Is.GreaterThan(0));
}
[Test]
public async Task UpdateProfileProcedure_runs_via_mediator()
{
var procedure = new UpdateProfileProcedure { Active = false, TypeId = 2, Name = "updated", Mandantor = "man2" };
var objectProc = procedure.ToObjectProcedure(45, "ReC.Tests");
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
Assert.That(result, Is.EqualTo(0));
}
[Test]
public async Task DeleteProfileProcedure_runs_via_mediator()
{
var procedure = new DeleteProfileProcedure { Start = 9, End = 10, Force = false };
var objectProc = procedure.ToObjectProcedure();
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
Assert.That(result, Is.EqualTo(0));
}
}

View File

@@ -0,0 +1,43 @@
using System.Linq;
using System.Threading.Tasks;
using MediatR;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using NUnit.Framework;
using ReC.Application.Profile.Queries;
using ReC.Tests.Application;
namespace ReC.Tests.Application.Profile;
[TestFixture]
public class ProfileQueryTests : RecApplicationTestBase
{
private (ISender Sender, IServiceScope Scope) CreateScopedSender()
{
var scope = ServiceProvider.CreateScope();
var sender = scope.ServiceProvider.GetRequiredService<ISender>();
return (sender, scope);
}
[Test]
public async Task ReadProfileViewQuery_returns_profile_from_database()
{
var profileId = Configuration.GetValue<long?>("FakeProfileId");
Assert.That(profileId, Is.Not.Null.And.GreaterThan(0), "FakeProfileId must be configured in appsettings.json");
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var profiles = await sender.Send(new ReadProfileViewQuery
{
Id = profileId,
IncludeActions = false
});
var profile = profiles.Single();
Assert.That(profile.Id, Is.EqualTo(profileId));
Assert.That(profile.ProfileName, Is.Not.Null.And.Not.Empty);
Assert.That(profile.Active, Is.True);
}
}

View File

@@ -0,0 +1,61 @@
using System.Threading.Tasks;
using MediatR;
using Microsoft.Extensions.DependencyInjection;
using NUnit.Framework;
using ReC.Application.Common.Procedures.DeleteProcedure;
using ReC.Application.Common.Procedures.InsertProcedure;
using ReC.Application.Common.Procedures.UpdateProcedure;
using ReC.Application.RecActions.Commands;
using ReC.Tests.Application;
namespace ReC.Tests.Application.RecActions;
[TestFixture]
public class RecActionProcedureTests : RecApplicationTestBase
{
private (ISender Sender, IServiceScope Scope) CreateScopedSender()
{
var scope = ServiceProvider.CreateScope();
var sender = scope.ServiceProvider.GetRequiredService<ISender>();
return (sender, scope);
}
[Test]
public async Task InsertActionProcedure_runs_via_mediator()
{
var procedure = new InsertActionProcedure { ProfileId = 1, Active = true, Sequence = 1 };
var objectProc = procedure.ToObjectProcedure("ReC.Tests");
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
Assert.That(result, Is.GreaterThan(0));
}
[Test]
public async Task UpdateActionProcedure_runs_via_mediator()
{
var procedure = new UpdateActionProcedure { ProfileId = 2, Active = false, Sequence = 2 };
var objectProc = procedure.ToObjectProcedure(35, "ReC.Tests");
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
Assert.That(result, Is.EqualTo(0));
}
[Test]
public async Task DeleteActionProcedure_runs_via_mediator()
{
var procedure = new DeleteActionProcedure { Start = 7, End = 8, Force = true };
var objectProc = procedure.ToObjectProcedure();
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
Assert.That(result, Is.EqualTo(0));
}
}

View File

@@ -0,0 +1,55 @@
using System.Linq;
using System.Threading.Tasks;
using DigitalData.Core.Exceptions;
using MediatR;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using NUnit.Framework;
using ReC.Application.RecActions.Queries;
using ReC.Tests.Application;
namespace ReC.Tests.Application.RecActions;
[TestFixture]
public class RecActionQueryTests : RecApplicationTestBase
{
private (ISender Sender, IServiceScope Scope) CreateScopedSender()
{
var scope = ServiceProvider.CreateScope();
var sender = scope.ServiceProvider.GetRequiredService<ISender>();
return (sender, scope);
}
[Test]
public async Task ReadRecActionViewQuery_returns_actions_for_profile()
{
var profileId = Configuration.GetValue<long?>("FakeProfileId");
Assert.That(profileId, Is.Not.Null.And.GreaterThan(0), "FakeProfileId must be configured in appsettings.json");
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var actions = await sender.Send(new ReadRecActionViewQuery
{
ProfileId = profileId
});
Assert.That(actions, Is.Not.Empty);
Assert.That(actions.All(a => a.ProfileId == profileId));
}
[Test]
public void ReadRecActionViewQuery_with_unknown_profile_throws_not_found()
{
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var invalidProfileId = long.MaxValue;
Assert.ThrowsAsync<NotFoundException>(async () =>
await sender.Send(new ReadRecActionViewQuery
{
ProfileId = invalidProfileId
}));
}
}

View File

@@ -0,0 +1,73 @@
using System;
using System.IO;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using ReC.Application;
using ReC.Application.Common.Options;
using ReC.Infrastructure;
namespace ReC.Tests.Application;
public abstract class RecApplicationTestBase : IDisposable
{
protected RecApplicationTestBase()
{
Configuration = BuildConfiguration();
ServiceProvider = BuildServiceProvider(Configuration);
}
protected IConfiguration Configuration { get; }
protected IServiceProvider ServiceProvider { get; }
private static IConfiguration BuildConfiguration()
{
var appSettingsPath = LocateApiAppSettings();
return new ConfigurationBuilder()
.AddJsonFile(appSettingsPath, optional: false, reloadOnChange: false)
.Build();
}
private static IServiceProvider BuildServiceProvider(IConfiguration configuration)
{
var services = new ServiceCollection();
services.AddSingleton(configuration);
services.AddRecServices(options =>
{
options.LuckyPennySoftwareLicenseKey = configuration["LuckyPennySoftwareLicenseKey"];
options.ConfigureRecActions(configuration.GetSection("RecAction"));
});
services.AddRecInfrastructure(opt =>
{
opt.ConfigureDbContext((_, builder) => builder.UseSqlServer(configuration.GetConnectionString("Default")));
});
return services.BuildServiceProvider();
}
private static string LocateApiAppSettings()
{
var current = new DirectoryInfo(AppContext.BaseDirectory);
while (current is not null)
{
var candidate = Path.Combine(current.FullName, "src", "ReC.API", "appsettings.json");
if (File.Exists(candidate))
return candidate;
current = current.Parent;
}
throw new FileNotFoundException("Could not locate src/ReC.API/appsettings.json from test base directory.");
}
public void Dispose()
{
if (ServiceProvider is IDisposable disposable)
disposable.Dispose();
}
}

View File

@@ -0,0 +1,61 @@
using System.Threading.Tasks;
using MediatR;
using Microsoft.Extensions.DependencyInjection;
using NUnit.Framework;
using ReC.Application.Common.Procedures.DeleteProcedure;
using ReC.Application.Common.Procedures.InsertProcedure;
using ReC.Application.Common.Procedures.UpdateProcedure;
using ReC.Application.Results.Commands;
using ReC.Tests.Application;
namespace ReC.Tests.Application.Results;
[TestFixture]
public class ResultProcedureTests : RecApplicationTestBase
{
private (ISender Sender, IServiceScope Scope) CreateScopedSender()
{
var scope = ServiceProvider.CreateScope();
var sender = scope.ServiceProvider.GetRequiredService<ISender>();
return (sender, scope);
}
[Test]
public async Task InsertResultProcedure_runs_via_mediator()
{
var procedure = new InsertResultProcedure { ActionId = 1, StatusId = 200, Header = "h", Body = "b" };
var objectProc = procedure.ToObjectProcedure("ReC.Tests");
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
Assert.That(result, Is.GreaterThan(0));
}
[Test]
public async Task UpdateResultProcedure_runs_via_mediator()
{
var procedure = new UpdateResultProcedure { ActionId = 2, StatusId = 500, Header = "h2", Body = "b2" };
var objectProc = procedure.ToObjectProcedure(55, "ReC.Tests");
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
Assert.That(result, Is.EqualTo(0));
}
[Test]
public async Task DeleteResultProcedure_runs_via_mediator()
{
var procedure = new DeleteResultProcedure { Start = 11, End = 12, Force = false };
var objectProc = procedure.ToObjectProcedure();
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var result = await sender.Send(objectProc);
Assert.That(result, Is.EqualTo(0));
}
}

View File

@@ -0,0 +1,34 @@
using DigitalData.Core.Exceptions;
using MediatR;
using Microsoft.Extensions.DependencyInjection;
using NUnit.Framework;
using ReC.Application.Results.Queries;
using ReC.Tests.Application;
namespace ReC.Tests.Application.Results;
[TestFixture]
public class ResultQueryTests : RecApplicationTestBase
{
private (ISender Sender, IServiceScope Scope) CreateScopedSender()
{
var scope = ServiceProvider.CreateScope();
var sender = scope.ServiceProvider.GetRequiredService<ISender>();
return (sender, scope);
}
[Test]
public void ReadResultViewQuery_with_unknown_action_throws_not_found()
{
var (sender, scope) = CreateScopedSender();
using var _ = scope;
var invalidActionId = long.MaxValue;
Assert.ThrowsAsync<NotFoundException>(async () =>
await sender.Send(new ReadResultViewQuery
{
ActionId = invalidActionId
}));
}
}

View File

@@ -0,0 +1,22 @@
using System.Reflection;
using ReC.Application.Common.Procedures.InsertProcedure;
using ReC.Application.Common.Procedures.UpdateProcedure;
namespace ReC.Tests.Application.Shared;
internal static class ProcedureObjectHelper
{
public static string? GetAddedWho(InsertObjectProcedure procedure)
{
return (string?)typeof(InsertObjectProcedure)
.GetProperty("AddedWho", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)?
.GetValue(procedure);
}
public static string? GetChangedWho(UpdateObjectProcedure procedure)
{
return (string?)typeof(UpdateObjectProcedure)
.GetProperty("ChangedWho", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)?
.GetValue(procedure);
}
}

View File

@@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0" />
<PackageReference Include="MediatR" Version="14.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.0" />
<PackageReference Include="Moq" Version="4.20.72" />
<PackageReference Include="NUnit" Version="3.14.0" />
<PackageReference Include="NUnit.Analyzers" Version="3.9.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\ReC.Application\ReC.Application.csproj" />
<ProjectReference Include="..\..\src\ReC.Infrastructure\ReC.Infrastructure.csproj" />
<ProjectReference Include="..\..\src\ReC.Domain\ReC.Domain.csproj" />
</ItemGroup>
<ItemGroup>
<Using Include="NUnit.Framework" />
</ItemGroup>
</Project>