繁体   English   中英

使用NSubstitute(或其他方法)进行Unity和自动模拟

[英]Unity and auto-mocking with NSubstitute (or something else)

我的问题来自于这个问题: Unity(代替温莎城堡)有可能吗?

这是答案中的课程:

protected override void Initialize()
{
    var strategy = new AutoMockingBuilderStrategy(Container);

    Context.Strategies.Add(strategy, UnityBuildStage.PreCreation);
}

class AutoMockingBuilderStrategy : BuilderStrategy
{
    private readonly IUnityContainer container;
    private readonly Dictionary<Type, object> substitutes 
       = new Dictionary<Type, object>();

    public AutoMockingBuilderStrategy(IUnityContainer container)
    {
        this.container = container;
    }

    public override void PreBuildUp(IBuilderContext context)
    {
        var key = context.OriginalBuildKey;

        if (key.Type.IsInterface && !container.IsRegistered(key.Type))
        {
            context.Existing = GetOrCreateSubstitute(key.Type);
            context.BuildComplete = true;
        }
    }

    private object GetOrCreateSubstitute(Type type)
    {
        if (substitutes.ContainsKey(type))
            return substitutes[type];

        var substitute = Substitute.For(new[] {type}, null);

        substitutes.Add(type, substitute);

        return substitute;
    }
}

在那里发布的解决方案对于单个对象非常适用。 如果看到发布的解决方案,则每次调用Resolve时,它将返回相同的对象

在如下所示的测试用例中可以这样做:

var myObjectWithInnerMockedObjects = UnityContainer.Resolve<ISomeInterface>();
var internalAutoMockedObject = UnityContainer.Resolve<IInnerInterface>();

在上述问题中发布的解决方案在上述情况下效果很好。

上面的代码通过Unity创建一个对象,并尝试解析构造函数参数,如果该类型未在unity config中映射,则通过NSubstitute返回一个模拟。

因此,有效的链条可以是:

- ActualObject
    - InnerActualObjectDependency
        - MockedDependency (since this was not mapped in Unity, a mock was created)

问题是如果我创建2个此类对象,则模拟指向相同的对象。

如果我在GetOrCreateSubstitute()方法中取消了CONTAINS检查,那么每次都会得到一个新的模拟...但是,如何访问特定对象的模拟以对其设置期望呢? :-(

我希望我对这个问题很清楚!

我们有一个内部团队讨论,我更好地理解嘲笑的意思是单身。 通过设计,我们不希望为每个创建的对象都使用不同的模拟对象。

模拟是针对类而非方法的。 因此,以下伪代码将是实现我正在做的事情的完美方法。

var obj1 = Resolve<IMyInterface>();
var obj2 = Resolve<IMyInterface>();
var innerDependency = Resolve<IInnerType>(); // Returns the same object that is shared by above 2 objs

innerDependency.SetExpection(Some expectation);
obj1.PerformAction();
innerDependency.Assert();

innerDependency.SetExpection(Some *different* expectation);
obj2.PerformAction();
innerDependency.Assert();

因此,这个问题的借口是错误的。 我们没有这种灵活性,因为我们不想这样做!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM