Skip to content

Instantly share code, notes, and snippets.

@michaeljbailey
Created October 28, 2014 16:11
Show Gist options
  • Save michaeljbailey/81c45ef16b083a50d680 to your computer and use it in GitHub Desktop.
Save michaeljbailey/81c45ef16b083a50d680 to your computer and use it in GitHub Desktop.
Allows sequencing of Moq'd objects to enforce specific call orders.
using System;
using System.Collections.Generic;
using System.Linq;
using Moq.Language.Flow;
namespace Moq.Sequencing
{
public static class CallSequenceExtensions
{
public static void InSequence<TMock>(this ISetup<TMock> setup, CallSequence callSequence) where TMock : class
{
callSequence.InSequence(setup);
}
}
internal class MockSequenceException : ApplicationException
{
public MockSequenceException(string message) : base(message)
{
}
}
public class CallSequence
{
private int _sequenceNumber;
private int _sequenceLength;
private readonly IList<string> _steps = new List<string>();
internal void InSequence<TMock>(ISetup<TMock> setup) where TMock : class
{
_steps.Add(setup.ToString());
var expectedSequenceNumber = _sequenceLength++;
setup.Callback(() => VerifySequence(expectedSequenceNumber));
}
private void VerifySequence(int expectedSequenceNumber)
{
if (_sequenceNumber == expectedSequenceNumber)
{
_sequenceNumber++;
}
else
{
var message =
string.Format(
"Expected call at step {0} but executed at step {1}. Expected sequence:{2}{3}",
expectedSequenceNumber + 1, _sequenceNumber + 1, Environment.NewLine,
string.Join(Environment.NewLine, _steps.Select((step, i) => string.Format("{0}) {1}", i + 1, step))));
throw new MockSequenceException(message);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment