0

我的问题源于这个问题: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 配置中映射,则通过 NSubstitute 返回一个模拟。

如此有效的链条可能是:

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

问题是如果我创建 2 个这样的对象,模拟指向同一个对象。

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

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

4

1 回答 1

1

我们进行了内部团队讨论,我更好地理解模拟是例的。按照设计,我们不希望每个创建的对象都有不同的模拟对象。

模拟用于类而不是方法。所以下面的伪代码将是实现我正在做的事情的完美方式。

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

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

于 2014-11-13T12:15:04.853 回答