式が短絡していることをテストする方法
-
10-07-2019 - |
質問
次のシグネチャを持つ拡張メソッドがあります:
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();
}
これは同じ原則ですが、より良い例外を提供します:)
所属していません StackOverflow