我根据这个 SO answer创建了一个扩展方法,用于按顺序调用 moq(见下文)。
一个示例用例是:
mock.setup.CallbackSequence(new List{h,e,l,l,o})
我hello
进入我SUT
的地方并期望角色按顺序排列。
问题是这种情况:
mock.setup.CallbackSequence(new List{h,e,l,l,o,X})
我经过的地方hello
。即使由于动态断言性质(X 从未发送过,但我们永远不知道)它应该失败,这也会通过。我能想到解决这个问题的唯一方法是添加一个
mock.Verify(setupmethod, Times.Exactly(list.Count))
但是,回调设置和验证是在两个不同的地方完成的,所以它会落在扩展方法的使用者身上来实现这个缺陷。我想避免把它放在他们身上,因为它一定会失败......建议?
public static ICallbackResult CallbackSequence<TMockType, T1, T2>(this ISetup<TMockType> mockSetup, IList<T1> sequencedList) where TMockType : class
{
//Refactor: Does not fail if it does not reach the end, only if out of order and/or too long
var index = 0;
return mockSetup.Callback((T1 t1, T2 t2) =>
{
if(index >= sequencedList.Count)
Assert.That(false, "Sequenced list attempted to access index out of bounds. Count is " + sequencedList.Count + "; index is " + index + "; value being checked is " + t1);
var currentItemInSequence = sequencedList[index];
Assert.That(t1, Is.EqualTo(currentItemInSequence), String.Format("Failed sequence at position{0}", index));
index++;
});
}
编辑
我能想到的唯一可行的方法是返回一个消费者应该在最后调用的自定义对象:
var sequenceVerifier = ...CallbackSequence();
//Do Stuff
sequenceVerifier.VerifySequence();
这对我来说仍然不是最佳的,因为这给人的印象是在调用 VerifySequence 之前它不会验证,但它只会执行边缘情况......除非我不在回调中断言,而只是跟踪和断言在最后???????这可能有效,想法????