web-dev-qa-db-ja.com

Moq Callback()呼び出しでの変数値の設定

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が初期化される前に使用される可能性があると文句を言います。

59
Adam Driscoll

これは、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>());
87
Mark Seemann

戻り値にパラメーターを指定するだけです...

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

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