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



我正在编写一些单元测试。直接从 NUnit 的文档中提取,我应该能够做这样的事情:

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()));

显然,我有两种解决方法,但我正在努力理解这里发生的事情。为什么我可以在 lambda 中new一个ExecutedRoutedEventArgs,该创建一个委托参数,但不创建另一个委托参数。

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

我正在使用VS2013,针对.net 4.0

我无法访问您在示例中使用的确切类,但是以下非常相似的代码在面向 .NET 4 的 VS 2013 中编译并运行良好。您是否正在使用 NUnit 2.6.3?此外,您正确地确定了在 lambda 外部创建实例与在 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
    {
    }
}

我没有 NUnit 来验证,但可能是您需要将 Lambda 显式转换为 Delegate 以强制正确的重载解决方案:

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

最新更新