From 7540890987764699b0b9f991ce4ea4edda1a6178 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Sun, 26 Sep 2010 17:22:44 -0700 Subject: [PATCH] Added Ninject.Moq --- .../Ninject.Moq/ExtensionsForBindingSyntax.cs | 33 ++++++++ .../Ninject.Moq/MockProvider.cs | 75 +++++++++++++++++++ .../Ninject.Moq/MockingKernel.cs | 41 ++++++++++ NzbDrone.Core.Test/NzbDrone.Core.Test.csproj | 8 ++ NzbDrone.Core.Test/SeriesTest.cs | 24 ++++++ 5 files changed, 181 insertions(+) create mode 100644 NzbDrone.Core.Test/Ninject.Moq/ExtensionsForBindingSyntax.cs create mode 100644 NzbDrone.Core.Test/Ninject.Moq/MockProvider.cs create mode 100644 NzbDrone.Core.Test/Ninject.Moq/MockingKernel.cs create mode 100644 NzbDrone.Core.Test/SeriesTest.cs diff --git a/NzbDrone.Core.Test/Ninject.Moq/ExtensionsForBindingSyntax.cs b/NzbDrone.Core.Test/Ninject.Moq/ExtensionsForBindingSyntax.cs new file mode 100644 index 000000000..82a0c5a90 --- /dev/null +++ b/NzbDrone.Core.Test/Ninject.Moq/ExtensionsForBindingSyntax.cs @@ -0,0 +1,33 @@ +using System; +using Ninject.Infrastructure; +using Ninject.Injection; +using Ninject.Planning.Bindings; +using Ninject.Syntax; + +namespace Ninject.Moq +{ + /// + /// Extensions for the fluent binding syntax API. + /// + public static class ExtensionsForBindingSyntax + { + /// + /// Indicates that the service should be bound to a mocked instance of the specified type. + /// + /// The service that is being mocked. + /// The builder that is building the binding. + public static IBindingWhenInNamedWithOrOnSyntax ToMock(this IBindingToSyntax builder) + { + var haveBinding = builder as IHaveBinding; + + if (haveBinding == null) + throw new NotSupportedException(String.Format("The binding builder for {0} is of type {1}, which does not implement IHaveBinding and is therefore not extensible.", typeof(T), builder.GetType())); + + IBinding binding = haveBinding.Binding; + + binding.ProviderCallback = ctx => new MockProvider(ctx.Kernel.Components.Get()); + + return builder as IBindingWhenInNamedWithOrOnSyntax; + } + } +} diff --git a/NzbDrone.Core.Test/Ninject.Moq/MockProvider.cs b/NzbDrone.Core.Test/Ninject.Moq/MockProvider.cs new file mode 100644 index 000000000..830e81c8b --- /dev/null +++ b/NzbDrone.Core.Test/Ninject.Moq/MockProvider.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using Moq; +using Ninject.Activation; +using Ninject.Injection; + +namespace Ninject.Moq +{ + /// + /// Creates mocked instances via Moq. + /// + public class MockProvider : IProvider + { + private static readonly Dictionary _injectors = new Dictionary(); + + /// + /// Gets the type (or prototype) of instances the provider creates. + /// + public Type Type + { + get { return typeof(Mock<>); } + } + + /// + /// Gets the injector factory component. + /// + public IInjectorFactory InjectorFactory { get; private set; } + + /// + /// Initializes a new instance of the class. + /// + /// The injector factory component. + public MockProvider(IInjectorFactory injectorFactory) + { + InjectorFactory = injectorFactory; + } + + /// + /// Creates an instance within the specified context. + /// + /// The context. + /// The created instance. + public object Create(IContext context) + { + ConstructorInjector injector = GetInjector(context.Request.Service); + var mock = injector.Invoke() as Mock; + return mock.Object; + } + + private ConstructorInjector GetInjector(Type service) + { + lock (_injectors) + { + Type mockType = typeof(Mock<>).MakeGenericType(service); + + if (_injectors.ContainsKey(mockType)) + return _injectors[mockType]; + + ConstructorInjector injector = InjectorFactory.Create(mockType.GetConstructor(Type.EmptyTypes)); + _injectors[mockType] = injector; + + return injector; + } + } + + /// + /// Gets a callback that creates an instance of the . + /// + /// The created callback. + public static Func GetCreationCallback() + { + return ctx => new MockProvider(ctx.Kernel.Components.Get()); + } + } +} diff --git a/NzbDrone.Core.Test/Ninject.Moq/MockingKernel.cs b/NzbDrone.Core.Test/Ninject.Moq/MockingKernel.cs new file mode 100644 index 000000000..40224b86f --- /dev/null +++ b/NzbDrone.Core.Test/Ninject.Moq/MockingKernel.cs @@ -0,0 +1,41 @@ +using System; +using Ninject.Activation.Caching; +using Ninject.Planning.Bindings; + +namespace Ninject.Moq +{ + /// + /// A kernel that will create mocked instances (via Moq) for any service that is + /// requested for which no binding is registered. + /// + public class MockingKernel : StandardKernel + { + /// + /// Clears the kernel's cache, immediately deactivating all activated instances regardless of scope. + /// This does not remove any modules, extensions, or bindings. + /// + public void Reset() + { + Components.Get().Clear(); + } + + /// + /// Attempts to handle a missing binding for a service. + /// + /// The service. + /// True if the missing binding can be handled; otherwise false. + protected override bool HandleMissingBinding(Type service) + { + var binding = new Binding(service) + { + ProviderCallback = MockProvider.GetCreationCallback(), + ScopeCallback = ctx => null, + IsImplicit = true + }; + + AddBinding(binding); + + return true; + } + } +} diff --git a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index 7c1333c11..d3c505380 100644 --- a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -42,6 +42,10 @@ False Moq\Moq.dll + + False + ..\NzbDrone.Core\Libraries\Ninject.dll + False ..\NzbDrone.Core\Libraries\SubSonic.Core.dll @@ -59,7 +63,11 @@ + + + + diff --git a/NzbDrone.Core.Test/SeriesTest.cs b/NzbDrone.Core.Test/SeriesTest.cs new file mode 100644 index 000000000..f3c429241 --- /dev/null +++ b/NzbDrone.Core.Test/SeriesTest.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Gallio.Framework; +using MbUnit.Framework; +using MbUnit.Framework.ContractVerifiers; +using Moq; +using NzbDrone.Core.Controllers; + +// ReSharper disable InconsistentNaming +namespace NzbDrone.Core.Test +{ + [TestFixture] + public class SeriesTest + { + [Test] + [Description("This test will confirm that a folder will be skipped if it has been resolved to a series already assigned to another folder")] + public void skip_same_series_diffrent_folder() + { + //Arrange + var seriesProvider = new SeriesController(new Mock(), new Mock(), new Mock(), new ) + } + } +}