1

this SO answerごとに moq を順番に呼び出すための拡張メソッドを作成しました (以下を参照) 。

使用例は次のとおりです。

mock.setup.CallbackSequence(new List{h,e,l,l,o})

hellomyに渡してSUT、順番に文字を期待します。

問題は次の場合です。

mock.setup.CallbackSequence(new List{h,e,l,l,o,X})

私が通過する場所hello。これは、動的アサーションの性質のために失敗する必要がありますが、合格します (X は送信されませんが、わかりません)。これを修正するために私が考えることができる唯一の方法は、追加することです

mock.Verify(setupmethod, Times.Exactly(list.Count))

ただし、コールバックのセットアップと検証は 2 つの異なる場所で行われるため、この欠陥を認識するのは拡張メソッドのコンシューマになります。失敗するに決まっているので、それを付けることは避けたいです.....提案はありますか?

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 が呼び出されるまで検証されないという印象を与えるため、まだ最適ではありませんが、エッジケースのみを実行します....コールバックでアサートしない限り、追跡してアサートするだけです。最後に???????それはうまくいくかもしれません、考え????

4

1 に答える 1

1

After talking with some co-workers, we came up with a dual approach that will leave it up to the implementer.

Option 1

Return a SequenceVerifier that must have its VerifySequenceCalls method called

Option 2

Pass my action into a helper method so that it can setup, act, and then verify the edge case

I can use a SequenceVerifier in my 2nd option. Then, it is up to the consumer how they want their code to look.

public static MockSequenceVerifier<T1> CallbackInOrderOfSequence<TMockType, T1, T2>(this ISetup<TMockType> mockSetup, IList<T1> sequencedList) where TMockType : class
{
  var mockSequenceVerifier = new MockSequenceVerifier<T1>(sequencedList);
  mockSetup.Callback((T1 t1, T2 t2) => mockSequenceVerifier.UpdateSequence(t1));
  return mockSequenceVerifier;
}

public static void VerifySequenceAfterActionPerformed<TMockType, T1, T2>(this ISetup<TMockType> mockSetup, IList<T1> sequencedList, Action actionToPerform) where TMockType : class
{
  var verifier = CallbackInOrderOfSequence<TMockType, T1, T2>(mockSetup, sequencedList);
  actionToPerform();
  verifier.VerifySequence();
}

public class MockSequenceVerifier<T>
{
  private IList<T> SequenceToVerifyAgainst { get; set; } 
  private IList<T> ActualSequence { get; set; } 

  public MockSequenceVerifier(IList<T> sequenceToVerifyAgainst)
  {
    SequenceToVerifyAgainst = sequenceToVerifyAgainst;
    ActualSequence = new List<T>();
  } 

  public void VerifySequence()
  {
    ActualSequence.IsEqualTo(SequenceToVerifyAgainst);
  }

  public void UpdateSequence(T item)
  {
    ActualSequence.Add(item);
  }
}
于 2013-06-20T21:04:48.063 に答える