在Moq Callback()调用中设置变量值

Ada*_*oll 61 .net c# unit-testing moq mocking

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

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>());
Run Code Online (Sandbox Code Playgroud)

这会引发异常,因为myFilteredFoosCast<IFooBar>()调用期间为null .这不符合我的预期吗?我认为FilterCollection会被调用,然后myFilteredFoos将是非null并允许演员.

FilterCollection是不是能够返回一个null,它使我得出它没有被调用的结论.另外,当我这样声明时myFilteredFoos:

Queryable myFilteredFoos;
Run Code Online (Sandbox Code Playgroud)

Return调用抱怨myFilteredFoos可以在初始化之前使用.

Mar*_*ann 88

这是因为Returns方法中的代码是立即评估的; 也就是说,在Setup调用该方法时.

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

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

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

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

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


小智 18

你可以在返回值中取参数...

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

      return myFilteredFoos.Cast<IFooBar>();
    });
Run Code Online (Sandbox Code Playgroud)