Как создать провайдера Moq для Ninject? - PullRequest
8 голосов
/ 29 июля 2011

Я хочу создать простой провайдер Ninject, который возвращает экземпляры Moq'd вместо конкретных типов. Пока у меня есть это:

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;
    }
}

Но это все неправильно, я уверен, потому что я не знаю, что я на самом деле делаю. Любая помощь и примеры кода будут великолепны. Я просто хочу умение делать:

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

или что-то в этом роде.

Обновление

Я понял, что могу добиться того, чего хочу, используя привязку метода Ninject:

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

Я все еще хотел бы более элегантный способ, и мне, возможно, придется проверить Ninject.Moq, как предложено Ианом, но если у кого-то есть реальные примеры кода, которые были бы великолепны.

Ответы [ 2 ]

8 голосов
/ 29 июля 2011

Обрабатывает ли расширение MockingKernel то, что вам нужно? Он имеет вкусы Moq, RhinoMocks и NSubstitute, а также доступен на NuGet.

0 голосов
/ 13 января 2017

Мое решение для этого всегда просто использует следующее:

MoqProvider

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

Затем я также регистрирую IMissingBindingResolver в моем ядре.MoqMissingBindingResolver просто создает новую привязку к MoqProvider для любой службы, для которой привязка еще не существует.

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>();
        }
    }
}

I Обычнотакже установите Settings.DefaultScopeCallback на одноэлементное значение, чтобы позднее я мог запрашивать свои макетированные объекты в своих тестах, когда мне нужно будет проверить, были ли определенные вызовы или не произошли, или настроить поведение на макетах до выполнения теста.Поэтому настройка моего ядра будет выглядеть следующим образом:

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

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

Надеюсь, это полезно.

...