From e3468daba04b52fbf41ce3004934a26b0220ec4f Mon Sep 17 00:00:00 2001 From: ta264 Date: Mon, 20 Jun 2022 20:25:47 +0100 Subject: [PATCH] Use DryIoc for Automoqer, drop Unity dependency [common] --- src/NzbDrone.Test.Common/AutoMoq/AutoMoqer.cs | 138 +++++++----------- .../Unity/AutoMockingBuilderStrategy.cs | 80 ---------- .../Unity/AutoMockingContainerExtension.cs | 35 ----- .../Radarr.Test.Common.csproj | 1 - 4 files changed, 55 insertions(+), 199 deletions(-) delete mode 100644 src/NzbDrone.Test.Common/AutoMoq/Unity/AutoMockingBuilderStrategy.cs delete mode 100644 src/NzbDrone.Test.Common/AutoMoq/Unity/AutoMockingContainerExtension.cs diff --git a/src/NzbDrone.Test.Common/AutoMoq/AutoMoqer.cs b/src/NzbDrone.Test.Common/AutoMoq/AutoMoqer.cs index dfd75c8db..b2846bf30 100644 --- a/src/NzbDrone.Test.Common/AutoMoq/AutoMoqer.cs +++ b/src/NzbDrone.Test.Common/AutoMoq/AutoMoqer.cs @@ -3,17 +3,11 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; -using System.Linq.Expressions; using System.Reflection; -using System.Runtime.CompilerServices; +using DryIoc; using Moq; -using Moq.Language.Flow; using NzbDrone.Common.Composition; using NzbDrone.Common.EnvironmentInfo; -using NzbDrone.Test.Common.AutoMoq.Unity; -using Unity; - -[assembly: InternalsVisibleTo("AutoMoq.Tests")] namespace NzbDrone.Test.Common.AutoMoq { @@ -21,32 +15,18 @@ namespace NzbDrone.Test.Common.AutoMoq public class AutoMoqer { public readonly MockBehavior DefaultBehavior = MockBehavior.Default; - public Type ResolveType; - private IUnityContainer _container; + private IContainer _container; private IDictionary _registeredMocks; public AutoMoqer() { - SetupAutoMoqer(new UnityContainer()); - } - - public AutoMoqer(MockBehavior defaultBehavior) - { - DefaultBehavior = defaultBehavior; - SetupAutoMoqer(new UnityContainer()); - } - - public AutoMoqer(IUnityContainer container) - { - SetupAutoMoqer(container); + SetupAutoMoqer(CreateTestContainer(new Container())); } public virtual T Resolve() { - ResolveType = typeof(T); var result = _container.Resolve(); SetConstant(result); - ResolveType = null; return result; } @@ -59,7 +39,6 @@ namespace NzbDrone.Test.Common.AutoMoq public virtual Mock GetMock(MockBehavior behavior) where T : class { - ResolveType = null; var type = GetTheMockType(); if (GetMockHasNotBeenCalledForThisType(type)) { @@ -78,90 +57,83 @@ namespace NzbDrone.Test.Common.AutoMoq public virtual void SetMock(Type type, Mock mock) { - if (_registeredMocks.ContainsKey(type) == false) + if (GetMockHasNotBeenCalledForThisType(type)) { _registeredMocks.Add(type, mock); } if (mock != null) { - _container.RegisterInstance(type, mock.Object); + _container.RegisterInstance(type, mock.Object, ifAlreadyRegistered: IfAlreadyRegistered.Replace); } } public virtual void SetConstant(T instance) { - _container.RegisterInstance(instance); + _container.RegisterInstance(instance, ifAlreadyRegistered: IfAlreadyRegistered.Replace); SetMock(instance.GetType(), null); } - public ISetup Setup(Expression> expression) - where T : class + private IContainer CreateTestContainer(IContainer container) { - return GetMock().Setup(expression); + var c = container.CreateChild(IfAlreadyRegistered.Replace, + container.Rules + .WithDynamicRegistration((serviceType, serviceKey) => + { + // ignore services with non-default key + if (serviceKey != null) + { + return null; + } + + if (serviceType == typeof(object)) + { + return null; + } + + if (serviceType.IsGenericType && serviceType.IsOpenGeneric()) + { + return null; + } + + // get the Mock object for the abstract class or interface + if (serviceType.IsInterface || serviceType.IsAbstract) + { + var mockType = typeof(Mock<>).MakeGenericType(serviceType); + var mockFactory = new DelegateFactory(r => + { + var mock = (Mock)r.Resolve(mockType); + SetMock(serviceType, mock); + return mock.Object; + }, Reuse.Singleton); + + return new[] { new DynamicRegistration(mockFactory, IfAlreadyRegistered.Keep) }; + } + + // concrete types + var concreteTypeFactory = serviceType.ToFactory(Reuse.Singleton, FactoryMethod.ConstructorWithResolvableArgumentsIncludingNonPublic); + + return new[] { new DynamicRegistration(concreteTypeFactory) }; + }, + DynamicRegistrationFlags.Service | DynamicRegistrationFlags.AsFallback)); + + c.Register(typeof(Mock<>), Reuse.Singleton, FactoryMethod.DefaultConstructor()); + + return c; } - public ISetup Setup(Expression> expression) - where T : class - { - return GetMock().Setup(expression); - } - - public void Verify(Expression> expression) - where T : class - { - GetMock().Verify(expression); - } - - public void Verify(Expression> expression, string failMessage) - where T : class - { - GetMock().Verify(expression, failMessage); - } - - public void Verify(Expression> expression, Times times) - where T : class - { - GetMock().Verify(expression, times); - } - - public void Verify(Expression> expression, Times times, string failMessage) - where T : class - { - GetMock().Verify(expression, times, failMessage); - } - - public void VerifyAllMocks() - { - foreach (var registeredMock in _registeredMocks) - { - var mock = registeredMock.Value as Mock; - if (mock != null) - { - mock.VerifyAll(); - } - } - } - - private void SetupAutoMoqer(IUnityContainer container) + private void SetupAutoMoqer(IContainer container) { _container = container; container.RegisterInstance(this); _registeredMocks = new Dictionary(); - RegisterPlatformLibrary(container); - AddTheAutoMockingContainerExtensionToTheContainer(container); + LoadPlatformLibrary(); AssemblyLoader.RegisterNativeResolver(new[] { "System.Data.SQLite", "Radarr.Core" }); } - private static void AddTheAutoMockingContainerExtensionToTheContainer(IUnityContainer container) - { - container.AddNewExtension(); - return; - } - private Mock TheRegisteredMockForThisType(Type type) where T : class { @@ -178,7 +150,7 @@ namespace NzbDrone.Test.Common.AutoMoq private bool GetMockHasNotBeenCalledForThisType(Type type) { - return _registeredMocks.ContainsKey(type) == false; + return !_registeredMocks.ContainsKey(type); } private static Type GetTheMockType() @@ -187,7 +159,7 @@ namespace NzbDrone.Test.Common.AutoMoq return typeof(T); } - private void RegisterPlatformLibrary(IUnityContainer container) + private void LoadPlatformLibrary() { var assemblyName = "Radarr.Windows"; diff --git a/src/NzbDrone.Test.Common/AutoMoq/Unity/AutoMockingBuilderStrategy.cs b/src/NzbDrone.Test.Common/AutoMoq/Unity/AutoMockingBuilderStrategy.cs deleted file mode 100644 index c841dc7d7..000000000 --- a/src/NzbDrone.Test.Common/AutoMoq/Unity/AutoMockingBuilderStrategy.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using Moq; -using Unity; -using Unity.Builder; -using Unity.Strategies; - -namespace NzbDrone.Test.Common.AutoMoq.Unity -{ - public class AutoMockingBuilderStrategy : BuilderStrategy - { - private readonly IUnityContainer _container; - private readonly MockRepository _mockFactory; - private readonly IEnumerable _registeredTypes; - - public AutoMockingBuilderStrategy(IEnumerable registeredTypes, IUnityContainer container) - { - var autoMoqer = container.Resolve(); - _mockFactory = new MockRepository(autoMoqer.DefaultBehavior); - _registeredTypes = registeredTypes; - _container = container; - } - - public override void PreBuildUp(ref BuilderContext context) - { - var autoMoqer = _container.Resolve(); - - var type = GetTheTypeFromTheBuilderContext(context); - if (AMockObjectShouldBeCreatedForThisType(type)) - { - var mock = CreateAMockObject(type); - context.Existing = mock.Object; - autoMoqer.SetMock(type, mock); - } - } - - private bool AMockObjectShouldBeCreatedForThisType(Type type) - { - var mocker = _container.Resolve(); - return TypeIsNotRegistered(type) && (mocker.ResolveType == null || mocker.ResolveType != type); - } - - private static Type GetTheTypeFromTheBuilderContext(BuilderContext context) - { - // return (context.OriginalBuildKey).Type; - return context.Type; - } - - private bool TypeIsNotRegistered(Type type) - { - return _registeredTypes.Any(x => x.Equals(type)) == false; - } - - private Mock CreateAMockObject(Type type) - { - var createMethod = GenerateAnInterfaceMockCreationMethod(type); - - return InvokeTheMockCreationMethod(createMethod); - } - - private Mock InvokeTheMockCreationMethod(MethodInfo createMethod) - { - return (Mock)createMethod.Invoke(_mockFactory, new object[] { new List().ToArray() }); - } - - private MethodInfo GenerateAnInterfaceMockCreationMethod(Type type) - { - var createMethodWithNoParameters = _mockFactory.GetType().GetMethod("Create", EmptyArgumentList()); - - return createMethodWithNoParameters.MakeGenericMethod(new[] { type }); - } - - private static Type[] EmptyArgumentList() - { - return new[] { typeof(object[]) }; - } - } -} diff --git a/src/NzbDrone.Test.Common/AutoMoq/Unity/AutoMockingContainerExtension.cs b/src/NzbDrone.Test.Common/AutoMoq/Unity/AutoMockingContainerExtension.cs deleted file mode 100644 index 71838c545..000000000 --- a/src/NzbDrone.Test.Common/AutoMoq/Unity/AutoMockingContainerExtension.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Collections.Generic; -using Unity.Builder; -using Unity.Extension; - -namespace NzbDrone.Test.Common.AutoMoq.Unity -{ - public class AutoMockingContainerExtension : UnityContainerExtension - { - private readonly IList _registeredTypes = new List(); - - protected override void Initialize() - { - SetEventsOnContainerToTrackAllRegisteredTypes(); - SetBuildingStrategyForBuildingUnregisteredTypes(); - } - - private void SetEventsOnContainerToTrackAllRegisteredTypes() - { - Context.Registering += (sender, e) => RegisterType(e.TypeFrom); - Context.RegisteringInstance += (sender, e) => RegisterType(e.RegisteredType); - } - - private void RegisterType(Type typeToRegister) - { - _registeredTypes.Add(typeToRegister); - } - - private void SetBuildingStrategyForBuildingUnregisteredTypes() - { - var strategy = new AutoMockingBuilderStrategy(_registeredTypes, Container); - Context.Strategies.Add(strategy, UnityBuildStage.PreCreation); - } - } -} diff --git a/src/NzbDrone.Test.Common/Radarr.Test.Common.csproj b/src/NzbDrone.Test.Common/Radarr.Test.Common.csproj index d1a70ff6b..4ff7fed27 100644 --- a/src/NzbDrone.Test.Common/Radarr.Test.Common.csproj +++ b/src/NzbDrone.Test.Common/Radarr.Test.Common.csproj @@ -9,7 +9,6 @@ -