我想我可能对Moq回调方法的语法有点困惑.当我试着做这样的事情时:

IFilter filter = new Filter();
List<IFoo> objects = new List<IFoo> { new Foo(), new Foo() };  

IQueryable myFilteredFoos = null;
mockObject.Setup(m => m.GetByFilter(It.IsAny<IFilter>()))
   .Callback( (IFilter filter) => myFilteredFoos = filter.FilterCollection(objects))
   .Returns(myFilteredFoos.Cast<IFooBar>());

这会引发异常,因为在Cast<IFooBar>()调用期间,myFilteredFoos为null.这不是我想的那样吗?我认为FilterCollection将被调用,然后myFilteredFoos将是非空的,并允许演员.

FilterCollection不能返回NULL,这使我得出它没有被调用的结论.另外,当我这样宣布myFilteredFoos时:

Queryable myFilteredFoos;

返回调用抱怨myFilteredFoos在初始化之前可能会被使用.

推荐答案

这是因为Returns方法中的代码会立即被判断;也就是说,当调用Setup方法时.

但是,在调用GetByFilter方法之前,不会调用回调.

幸运的是,Returns方法已重载,因此您也可以推迟其执行:

mockObject.Setup(m => m.GetByFilter(It.IsAny<IFilter>()))
    .Callback((IFilter filter) =>
        myFilteredFoos = filter.FilterCollection(objects))
    .Returns(() => myFilteredFoos.Cast<IFooBar>());

但是,您不需要在回调中保存该值,因为您可以直接在Returns方法中获取参数值:

mockObject.Setup(m => m.GetByFilter(It.IsAny<IFilter>()))
    .Returns((IFilter filter) =>
        filter.FilterCollection(objects).Cast<IFooBar>());

.net相关问答推荐

无法在Designer、VS2022、. NET 8中打开WinForms表单'

有没有更好的方法使用 Pusher Channels 的批事件发布消息?

为什么这个同步运行的异步睡眠会挂起?

"投掷;" 是什么意思?靠自己做什么?

为什么这两个比较有不同的结果?

lock() 是否保证按请求的顺序获得?

.Net 中的 Int128?

如何等到远程 .NET 调试器附加

[DllImport("QCall")] 是什么?

在安全处理异常时避免首次机会异常消息

有没有像样的 C# 分析器?

DataGridView 在我的两个屏幕之一上的可怕重绘性能

C# 中的 override 和 new 关键字有什么区别?

是否可以完全用托管的 .NET 语言编写 JIT 编译器(本地代码)

为什么发布和调试模式下的代码行为不同?

微软内部 PriorityQueue 中的错误?

是否可以在 XP 上运行 .NET 4.5 应用程序?

如何修复 .NET Windows 应用程序在启动时崩溃并出现异常代码:0xE0434352?

使用 DateTime.ToString() 时获取日期后缀

/langversion 的错误选项6无效;必须是 ISO-1、ISO-2、3、4、5 或默认值