Значения параметров настройки в вызове 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 может использоваться до его инициализации.
Ответы
Ответ 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>();
});