8 Stimmen

Wie erstellt man einen Moq-Anbieter für Ninject?

Ich möchte einen einfachen Ninject-Anbieter erstellen, der Moq'd-Instanzen anstelle von konkreten Typen zurückgibt. Bis jetzt habe ich dies:

public class NinjectMockProvider<T> : IProvider
{
    public static Type Type { get { return typeof(T); } }

    public object Create(IContext context)
    {
        Mock<T> newMock = new Mock<T>();
        return newMock.Object;
    }
}

Aber ich bin mir sicher, dass das alles falsch ist, denn ich weiß nicht, was ich wirklich tue. Jede Hilfe und Codebeispiele wären großartig. Ich möchte nur die Fähigkeit zu tun:

kernel.Bind<ISomeInterface>().ToProvider<NinjectMoqProvider<ISomeInterface>>();

oder etwas in dieser Richtung.

Update

Ich habe herausgefunden, dass ich mit der Methodenbindung von Ninject erreichen kann, was ich will:

kernel.Bind<ISomeInterface>().ToMethod(x => new Mock<ISomeInterface>().Object);

Ich möchte immer noch einen eleganteren Weg, und ich muss vielleicht Ninject.Moq überprüfen, wie von Ian vorgeschlagen, aber wenn jemand irgendwelche echten Code-Beispiele hat, wäre das großartig.

0 Stimmen

Danke, das Beispiel der Methodenbindung ist großartig

8voto

Ian Davis Punkte 3808

Ist die MockingKernel Erweiterung mit dem, was Sie brauchen? Es hat Moq, RhinoMocks und NSubstitute Flavors, und es ist auch auf NuGet verfügbar.

0 Stimmen

Ich bin sicher, dass es wahrscheinlich, aber ich war auf der Suche nach meiner eigenen einfachen Wrapper nur so konnte ich es besser verstehen.

1 Stimmen

Ich würde empfehlen, sich den Quellcode der Erweiterungen anzuschauen, da er einen Einblick in Mocking Kernels geben kann.

0voto

s3raph86 Punkte 548

Meine Lösung für dieses Problem ist immer die folgende:

MoqProvider

public class MoqProvider<T> : Provider<T> // T is the desired service
{
    protected override T CreateInstance(IContext context)
    {
        return new Mock<T>().Object;
    }
}

Ich registriere dann auch eine IMissingBindingResolver mit meinem Kernel. Die MoqMissingBindingResolver erstellt einfach eine neue Bindung an eine MoqProvider für jeden Dienst, für den noch keine Bindung besteht.

MoqMissingBindingResolver

public class MoqMissingBindingResolver : NinjectComponent, IMissingBindingResolver
{
    public IEnumerable<IBinding> Resolve(Multimap<Type, IBinding> bindings, IRequest request)
    {
        if (request.Service.IsAbstract || request.Service.IsInterface)
        {
            var moqProvider = (IProvider)Activator.CreateInstance(typeof(MoqProvider<>).MakeGenericType(request.Service));
            return new IBinding[] 
            { 
                new Binding(request.Service, new BindingConfiguration 
                { 
                    ProviderCallback = ctx => moqProvider,
                    ScopeCallback    = Settings.DefaultScopeCallback
                }) 
            }; 
        }
        else
        {
            return Enumerable.Empty<IBinding>();
        }
    }
}

Ich stelle normalerweise auch Settings.DefaultScopeCallback in Singleton umgewandelt, so dass ich meine Mocked-Objekte in meinen Tests später abfragen kann, wenn ich überprüfen muss, ob bestimmte Aufrufe stattgefunden haben oder nicht, oder das Verhalten der Mocks vor der Ausführung des Tests einrichten muss. Das Einrichten meines Kernels sieht also wie folgt aus:

INinjectSettings Settings = new NinjectSettings 
{ 
    DefaultScopeCallback = StandardScopeCallbacks.Singleton    
};

var k = new StandardKernel(Settings);
k.Components.Add<IMissingBindingResolver, MoqMissingBindingResolver>();

Ich hoffe, dies ist hilfreich.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X