4

モッキング ライブラリMoqには、署名付きの Setup() メソッドがあります。

public ISetup<T, TResult> Setup<TResult>(Expression<Func<T, TResult>> expression)

だから私はこのようなことをうまくやることができます(ライブラリの再帰的モックを使用して):

Mock<Thing> _thing = new Mock<Thing>();
_thing.Setup((Thing t) => t.PropA.SubPropB).Returns(string.Empty);

しかし、これは失敗します:

Expression<Func<Thing, object>> test = (Thing t) => t.PropA.SubPropB;
_thing.Setup(test).Returns(string.Empty);

エラーで:

Expression is not a method invocation: t => (Object)t.PropA.SubPropB

インライン化されたラムダと最初に変数に割り当てられたラムダの違いは何ですか? 式ツリーと未コンパイルの両方ではありませんか (Moq はツリーを解析します)。

編集 - 問題はFunc<Thing, object>タイピングにあるようです。たとえば、string受け入れられるのに、受け入れられないのobjectはなぜですか?

4

1 に答える 1

3

たとえば、文字列は受け入れられるのに、オブジェクトは受け入れられないのはなぜですか?

の関数宣言moqはジェネリック型によって共変ではないためです。次の方法でmoqをセットアップしてみてください

 _thing.Setup(test).Returns((object)string.Empty);

次の署名がExpression<Func<Thing, object>>あり、それに関して共変ではないためobject

または、署名を次のように変更します(文字列を返すstringと仮定します)。t.PropA.SubPropB

Expression<Func<Thing, string>> test = (Thing t) => t.PropA.SubPropB;
                        //^here should be string

実際のケースExpressionでは、ローカル変数として テスト プロジェクトを作成しましたが、すべて正常に動作しstringobject. 何か見逃した場合は、構成を確認してください。Moq - 4.0.10827v

[TestFixture]
public class Class1
{
    [Test]
    public void TestMethod()
    {
        Mock<Thing> _thing = new Mock<Thing>();

        Expression<Func<Thing, string>> setup = t => t.PropA.SubPropB;
//                               ^ works with string and object
        _thing.Setup(setup).Returns(string.Empty);

        Assert.IsEmpty(_thing.Object.PropA.SubPropB);

    }
}

public class Thing
{
    public virtual Thingy PropA { get; set; }
}

public class Thingy
{
    public virtual string SubPropB { get; set; }
}
于 2013-01-15T22:00:59.933 に答える