【问题标题】:How to test that an expression is short-circuited如何测试表达式是否短路
【发布时间】:2009-11-30 14:51:49
【问题描述】:

我有一个带有以下签名的扩展方法:

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

我已经为它编写了一个测试用例,以确保这两个表达式实际上是结合在一起的。至少这样我得到的新表达式才有效。

现在我想编写另一个测试用例,以确保该方法使用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 的整个语句体下方看到一个巨大的红色波浪线,指出“不能将带有语句体的 lambda 表达式转换为表达式树”。所以……有什么选择吗?或者这是一个不可能编写的测试?

【问题讨论】:

  • 你把一些真假混淆了。
  • 糟糕。想我现在设法得到它..:p
  • 只是关于错误的简短说明。单行 lambda 表达式或表达式 lambda(“a” case)和表达式树之间存在隐式转换,但多行 lambda 表达式或语句 lambda(“b” case)和表达式树之间没有隐式转换.有关详细信息,请参阅blogs.msdn.com/csharpfaq/archive/2009/09/14/…

标签: c# unit-testing lambda expression-trees


【解决方案1】:

简单的建议:使用引用类型而不是值类型,并在您不希望遵循的路径中取消引用它。传入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();
}

原理相同,但它会给你一个更好的例外:)

【讨论】:

  • 你是怎么想出这些东西的...? :p -- 谢谢! :D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-17
  • 2013-08-25
  • 2019-08-27
  • 2015-12-23
  • 2017-05-23
  • 2011-04-13
  • 2012-06-02
相关资源
最近更新 更多