0

私の質問は、この質問から派生したものです:これは Unity (Castle Windsor の代わりに) で可能ですか?

答えからのクラスは次のとおりです。

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

そこに投稿されたソリューションは、SINGLE オブジェクトに対してうまく機能します。ソリューションが投稿されている場合は、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 に答える