質問

次のシグネチャを持つ拡張メソッドがあります:

public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
{
    ...
}

2つの式が実際に結合されることを確認するためのテストケースを作成しました。少なくとも、新しい表現が機能するように。

ここで、メソッドが and の短絡バージョンを使用することを確認するだけの別のテストケースを書きたいと思います。どのようにこれを行うことができますか?

このようなことができると思った:

    [Test]
    public void And_PredicatesAreShortCircuited()
    {
        var predicateNotUsed = true;
        Expression<Func<int, bool>> a = x => false;
        Expression<Func<int, bool>> b = x =>
            {
                predicateNotUsed = false;
                return true;
            };

        var foo = new[] { 1, 2, 3, 4, 5, 6, 7 }
            .Where(a.And(b).Compile())
            .ToArray();

        Assert.That(predicateNotUsed);
    }

ただし、 b のステートメント本文全体の下に巨大な赤い波線が表示されます。これは、&quot;ステートメント本文のラムダ式は式ツリーに変換できないことを示しています 。だから...オプションはありますか?または、これは書くことが不可能なテストですか?

役に立ちましたか?

解決

単純な提案:値型の代わりに参照型を使用し、フォローしたくないパスでそれを間接参照します。 nullを渡し、例外をスローするかどうかを確認します:)

[Test]
public void And_PredicatesAreShortCircuited()
{
    Expression<Func<string, bool>> a = x => false;
    Expression<Func<string, bool>> b = x => x.Length > 10;

    var foo = new[] { null, null }
        .Where(a.And(b).Compile())
        .ToArray();
}

別の代替方法は、入力データに何らかの副作用関数を使用することです(たとえば、式ツリーで変更できるものを渡す)が、上記がおそらく最も簡単なアプローチになると思います:)

または別のアイデア:

public T NonVoidFail(T x)
{
    Assert.Fail("I shouldn't be called");
    return x; // Will never happen
}

その後:

[Test]
public void And_PredicatesAreShortCircuited()
{
    Expression<Func<int, bool>> a = x => false;
    Expression<Func<int, bool>> b = x => NonVoidFail(x);

    var foo = new[] { 1, 2, 3, 4, 5, 6, 7 }
        .Where(a.And(b).Compile())
        .ToArray();
}

これは同じ原則ですが、より良い例外を提供します:)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top