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

时间:2015-02-25 20:49:11

标签: c# microsoft-fakes

我有这样的界面:

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)
   ...

如何将第二次调用存根到此方法?

1 个答案:

答案 0 :(得分:0)

看起来MSFakes在内部构建一个字典,返回类型为键,Func委托为值。不幸的是,在您设置一次后,它不会让您更改代理。

所以这样的事情还可以:

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

但这会引发异常,因为它试图两次使用相同的返回类型:

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次或更多次方法,祝你好运。