NUnit测试中的Lambdas和委托类型:编译器错误

时间:2014-02-28 16:58:57

标签: c# lambda nunit

我正在写一些单元测试。直接从NUnit的documentation开始,我应该能够做到这样的事情:

Assert.That( SomeMethod, Throws.ArgumentException );

在测试方法中,这不会编译:

Assert.That(()=>viewModel.SaveCommand_Exec(this, new ExecutedRoutedEventArgs()),
  Throws.Nothing);
// Compiler error:
// Cannot convert lambda expression to type 'bool'
// because it is not a delegate type

但这会:

ExecutedRoutedEventArgs e = new ExecutedRoutedEventArgs();
Assert.That(() => viewModel.SaveCommand_Exec(this, e), Throws.Nothing);

这样:

Assert.DoesNotThrow(()=>viewModel.SaveCommand_Exec(this,
  new ExecutedRoutedEventArgs()));

显然,我有两个解决方法,但我正在努力了解这里发生了什么。为什么new可以在lambda中创建一个ExecutedRoutedEventArgs来创建一个委托参数而不是另一个委托参数。

更有趣的是,在lambda之外创建EventArgs对象而不是在其内部的区别究竟是什么?我意识到这会创建一个闭包,但我不明白它是如何改变匿名方法的签名的。

我正在使用VS2013,目标是.net 4.0

2 个答案:

答案 0 :(得分:2)

我无法访问您在示例中使用的确切类,但以下非常相似的代码在针对.NET 4的VS 2013中编译并运行正常。您使用的是NUnit 2.6.3吗?此外,您正确地确定了在lambda之外创建ExecutedRoutedEventArgs实例而不是在其内部之间的唯一区别:闭包。

using NUnit.Framework;

namespace ConsoleApplication1
{
    internal class Program
    {
        private static void Main()
        {
            var viewModel = new ViewModel();

            Assert.That(() => viewModel.SaveCommand_Exec(null, new ExecutedRoutedEventArgs()), Throws.Nothing);
        }
    }

    public class ViewModel
    {
        public bool SaveCommand_Exec(object sender, ExecutedRoutedEventArgs e)
        {
            return true;
        }
    }

    public class ExecutedRoutedEventArgs
    {
    }
}

答案 1 :(得分:1)

我没有NUnit来验证,但可能需要将Lambda明确地转换为Delegate以强制进行适当的重载解析:

 Assert.That((Action)(()=>viewModel.SaveCommand_Exec(this, new ExecutedRoutedEventArgs())),
                Throws.Nothing);