MSFakes,我如何将此调用存根两次?

MSFakes, how do I stub this call twice?

我有这样的界面:

IDbSession
{
    IEnumerable<T> Query<T>(string sql, object param = null);
}

MSFakes 生成一个如下所示的对象:

class StubIDbSession : StubBase<IDbSession>, IDbSession, IDisposable
{
    public void QueryOf1StringObject<T>(FakesDelegates.Func<string, object, System.Collections.Generic.IEnumerable<T>> stub);
}

然后我这样使用:

var session = new StubIDbSession();
session.QueryOf1StringObject((sql1, param1) =>
{
    // Stub the second call
    session.QueryOf1StringObject((sql2, param2) => new List<MyDto>());

    return myDtos.Take(1);
});

然而,当第二次调用时,它抛出这个异常:

ArgumentException: An item with the same key has already been added.

   at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
   at Microsoft.QualityTools.Testing.Fakes.Stubs.StubDelegateMap.Concat(StubDelegateMap dictionary, Delegate delegate)
   ...

我怎样才能对这个方法的第二次调用打桩?

看起来 MSFakes 在内部构建了一个字典,其中 return 类型作为键,Func 委托作为值。不幸的是,它不允许您在设置一次后更改委托。

所以这样的事情是可以的:

var session = new StubIDbSession();
session.QueryOf1StringObject((sql1, param1) =>
{
    return new List<string>();
});
session.QueryOf1StringObject((sql1, param1) =>
{
    return new List<int>();
});

但这会抛出异常,因为它试图使用相同的 return 类型两次:

var session = new StubIDbSession();
session.QueryOf1StringObject((sql1, param1) =>
{
    return new List<string> { "STRING 1" }
});
session.QueryOf1StringObject((sql1, param1) =>
{
    return new List<string> { "STRING 2" }
});

以下是我的解决方法:

bool called = false;
session.QueryOf1StringObject((sql1, param1) =>
{
    if(called)
    {
        return new List<string> { "STRING 2" };
    }
    else
    {
        called = true;
        return new List<string> { "STRING 1" }
    }
});

如果您需要调用一个方法 3 次或更多次,祝您好运。