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>());
_
Cast<IFooBar>()
呼び出し中にmyFilteredFoos
がnullであるため、これは例外をスローします。これは期待どおりに機能していませんか? FilterCollection
が呼び出され、myFilteredFoos
がnullでなく、キャストが可能になると思います。
FilterCollection
はnullを返すことができないため、呼び出されていないという結論に至ります。また、次のようにmyFilteredFoos
を宣言すると:
_Queryable myFilteredFoos;
_
Return呼び出しは、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>());
戻り値にパラメーターを指定するだけです...
mockObject
.Setup(m => m.GetByFilter(It.IsAny<IFilter>()))
.Returns((IFilter filter) =>
{
myFilteredFoos = filter.FilterCollection(objects);
return myFilteredFoos.Cast<IFooBar>();
});