如何对返回Func <something>的C#函数进行单元测试?

goo*_*gic 8 c# lambda unit-testing

我有一个包含一个方法的类,该方法返回一个Result对象,该对象包含一个Func类型的属性.

class Result {
   public Func<Result> NextAction { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

如何编写关于此Func内容的单元测试断言?以下显然不起作用,因为编译器为lambda生成两种不同的方法:

// Arrange
ListController controller = new ListController(domain);
// Act
Result actual = controller.DefaultAction();
// Assert
Func<Result> expected = () => new ProductsController(domain).ListAction();
Assert.That(actual.NextAction, Is.EqualTo(expected));
Run Code Online (Sandbox Code Playgroud)

我猜我可以通过使用表达式树来实现这一点,但是......有没有办法避免这样做?我正在使用NUnit 2.5.

编辑:Result对象中没有其他标识字段.它旨在基于在当前对象/方法中做出的决定来调用下一个对象/方法.

goo*_*gic 0

看来单元测试的内容Func超出了单元测试的正常范围。AFunc代表已编译的代码,因此在不解析 MSIL 的情况下无法进一步检查。因此,在这种情况下,有必要依靠委托和实例化类型(如 Nathan Baulch 所建议的),或者改用表达式树。

我的表达式树等效如下:

class Result {
   public Expression<Func<Result>> NextAction { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

单元测试如下:

// Arrange
ListController controller = new ListController(domain);
// Act
Result actual = controller.DefaultAction();
// Assert
MethodCallExpression methodExpr = (MethodCallExpression)actual.NextAction.Body;
NewExpression newExpr = (NewExpression)methodExpr.Object;
Assert.That(newExpr.Type, Is.EqualTo(typeof(ProductsController)));
Assert.That(methodExpr.Method.Name, Is.EqualTo("ListAction"));
Run Code Online (Sandbox Code Playgroud)

请注意,此测试存在一些固有的脆弱性,因为它暗示了表达式的结构及其行为。