From 3024d54410246490b97fcfb1e70c14bd9acf1a22 Mon Sep 17 00:00:00 2001 From: Bart Koelman Date: Wed, 16 Jun 2021 18:08:30 +0200 Subject: [PATCH] Added tests that validate the IoC container is configured correctly --- .../DependencyContainerRegistrationTests.cs | 122 ++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 test/JsonApiDotNetCoreExampleTests/UnitTests/Configuration/DependencyContainerRegistrationTests.cs diff --git a/test/JsonApiDotNetCoreExampleTests/UnitTests/Configuration/DependencyContainerRegistrationTests.cs b/test/JsonApiDotNetCoreExampleTests/UnitTests/Configuration/DependencyContainerRegistrationTests.cs new file mode 100644 index 0000000000..39ce4b29d1 --- /dev/null +++ b/test/JsonApiDotNetCoreExampleTests/UnitTests/Configuration/DependencyContainerRegistrationTests.cs @@ -0,0 +1,122 @@ +using System; +using FluentAssertions; +using JetBrains.Annotations; +using JsonApiDotNetCore; +using JsonApiDotNetCoreExample.Startups; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Xunit; + +namespace JsonApiDotNetCoreExampleTests.UnitTests.Configuration +{ + public sealed class DependencyContainerRegistrationTests + { + [Fact] + public void Can_resolve_registered_services_from_example_project() + { + // Arrange + IHostBuilder hostBuilder = CreateValidatingHostBuilder(); + + // Act + using IHost _ = hostBuilder.Build(); + } + + [Fact] + public void Cannot_resolve_registered_services_with_conflicting_scopes() + { + // Arrange + IHostBuilder hostBuilder = CreateValidatingHostBuilder(); + + hostBuilder.ConfigureServices(services => + { + services.AddScoped(); + services.AddSingleton(); + }); + + // Act + Action action = () => + { + using IHost _ = hostBuilder.Build(); + }; + + // Assert + action.Should().ThrowExactly().WithMessage("Some services are not able to be constructed * " + + "Singleton * Cannot consume scoped service *"); + } + + [Fact] + public void Cannot_resolve_registered_services_with_circular_dependency() + { + // Arrange + IHostBuilder hostBuilder = CreateValidatingHostBuilder(); + + hostBuilder.ConfigureServices(services => + { + services.AddScoped(); + services.AddScoped(); + }); + + // Act + Action action = () => + { + using IHost _ = hostBuilder.Build(); + }; + + // Assert + action.Should().ThrowExactly().WithMessage("Some services are not able to be constructed * " + + "A circular dependency was detected *"); + } + + private static IHostBuilder CreateValidatingHostBuilder() + { + IHostBuilder hostBuilder = Host.CreateDefaultBuilder().ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + + webBuilder.UseDefaultServiceProvider(options => + { + options.ValidateScopes = true; + options.ValidateOnBuild = true; + }); + }); + + return hostBuilder; + } + + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] + private sealed class SomeSingletonService + { + // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local + public SomeSingletonService(SomeScopedService scopedService) + { + ArgumentGuard.NotNull(scopedService, nameof(scopedService)); + } + } + + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] + private sealed class SomeScopedService + { + } + + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] + private sealed class CircularServiceA + { + // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local + public CircularServiceA(CircularServiceB serviceB) + { + ArgumentGuard.NotNull(serviceB, nameof(serviceB)); + } + } + + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] + private sealed class CircularServiceB + { + // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local + public CircularServiceB(CircularServiceA serviceA) + { + ArgumentGuard.NotNull(serviceA, nameof(serviceA)); + } + } + } +}