Подтвердить что ты не робот

Значения параметров настройки в вызове Moq Callback()

Я думаю, что я могу немного смутить синтаксис методов обратного вызова 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>());

Это вызывает исключение, поскольку myFilteredFoos имеет значение null во время вызова Cast<IFooBar>(). Неужели это не работает, как я ожидаю? Я бы подумал, что FilterCollection будет вызываться, а затем myFilteredFoos будет не нулевым и позволит выполнить трансляцию.

FilterCollection не может возвращать нуль, который привлекает меня к выводу, который он не вызывается. Кроме того, когда я объявляю myFilteredFoos следующим образом:

Queryable myFilteredFoos;

Обратный вызов жалуется, что myFilteredFoos может использоваться до его инициализации.

4b9b3361

Ответ 1

Это потому, что код в методе 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>());

Ответ 2

Вы можете просто взять параметр в возвращаемом значении...

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

      return myFilteredFoos.Cast<IFooBar>();
    });