Ninject和动态WithConstructor/WithMeta和RhinoMocks

本文关键字:WithMeta RhinoMocks WithConstructor 动态 Ninject | 更新日期: 2023-09-27 18:09:46

在我的项目中,我有一个IoC容器,它使用ServiceModule以通常的方式初始化。当我编写单元测试时,我希望能够绑定到StrictMock、DynamicMock、PartialMock或Stub。在过去,我有一个FakeServiceModule,它将所有内容绑定到strictmock,但这是非常限制的,我想扩展它以允许创建我选择的模拟类型。

为了达到这个目的,我创建了如下命令:

public class NinjectMocking
{
    public Type TypeToMock { get; set; }
    public MockType MockTypeToUse { get; set; }
    public IBindingWithOrOnSyntax<Type> BindingWithOrOnSyntax { get; set; }   
}
public enum MockType
{
    Stub,
    Strict,
    Dynamic,
    Partial
}
我的想法是,我将像这样初始化伪服务模块:
        foreach (var mockType in _mocks)
        {
            object ninjaMock;
            switch (mockType.MockTypeToUse)
            {
                case MockType.Strict:
                    {
                        ninjaMock = _mockRepository.StrictMock(mockType.TypeToMock);
                        break;
                    }
                case MockType.Dynamic:
                    {
                        ninjaMock = _mockRepository.DynamicMock(mockType.TypeToMock);
                        break;
                    }
                case MockType.Partial:
                    {
                        ninjaMock = _mockRepository.PartialMock(mockType.TypeToMock);
                        break;
                    }
                case MockType.Stub:
                    {
                        ninjaMock = _mockRepository.Stub(mockType.TypeToMock);
                        break;
                    }
                default:
                    {
                        ninjaMock = _mockRepository.StrictMock(mockType.TypeToMock);
                        break;
                    }
            }
            if (mockType.BindingWithOrOnSyntax == typeof(ConstructorArgument))
                Bind(mockType.TypeToMock).ToMethod(m => ninjaMock).w
                    .WithConstructorArgument(mockType.BindingWithOrOnSyntax);
            else
                Bind(mockType.TypeToMock).ToMethod(m => ninjaMock);
        }

用mock列表初始化后…

       NinjectMocking ninjectMocking = new NinjectMocking();
        ninjectMocking.TypeToMock = typeToAdd;
        ninjectMocking.MockTypeToUse = MockType.Dynamic;

这一切都很完美。然而,问题来了,我们的一些绑定需要。withconstructorargument或。withmetadata,如

        Bind<ISomeRepository>().ToMethod(m => someRepository)
        .WithConstructorArgument("context", ctx => new TestDataContext());

,也许将来会有其他的。这就是为什么我在NinjectMocking类中有BindingWithOrOnSyntax属性。所以我的新初始化项可能是这样的:

        NinjectMocking ninjectMocking = new NinjectMocking();
        ninjectMocking.TypeToMock = typeToAdd;
        ninjectMocking.MockTypeToUse = MockType.Dynamic;
        ninjectMocking.BindingWithOrOnSyntax.WithConstructorArgument("context", constructorArgument);

问题是我不知道如何在绑定中使用它。我想做的是像

这样的东西

绑定(mockType.TypeToMock)。method (m => ninjaMock).[WhatGoesHere]

我真的不知道如何用[WhatGoesHere]位来做,或者如何定义绑定,以便它使用我传入的任何东西,在BindingWithOrOnSyntax属性。我最后一次绝望的尝试是通过像

这样的东西强迫它
            if (mockType.BindingWithOrOnSyntax == typeof(ConstructorArgument))
                Bind(mockType.TypeToMock).ToMethod(m => ninjaMock)
                    .WithConstructorArgument(mockType.BindingWithOrOnSyntax);

但这显然行不通。

任何正确方向的指示,或者即使有更好的方法来实现这一点,将不胜感激。

Ninject和动态WithConstructor/WithMeta和RhinoMocks

不要在单元测试期间使用IOC容器。IOC容器将在运行时用于将依赖项注入到组件中。在单元测试期间,创建带有模拟/存根依赖的组件。如果您的组件直接从IOC容器解析依赖项,那么您没有正确地使用容器。