Knocked up this handy little extension method last week to help us mock the use of IDbCommand (and its associated classes) to test some ADO.NET code. The idea is that you pass in the text and type of the command, and an anonymous type representing the parameter names and values that you expect it to be called with.

public static Mock<IDbCommand> CreateDbCommand<T>(this MockFactory factory, 
    string commandText, CommandType commandType, T parameters)
    where T : class
{
    var cmd = factory.Create<IDbCommand>();
    var parms = factory.Create<IDataParameterCollection>();

    var pq = new Queue<IDbDataParameter>();

    foreach (var prop in parameters.GetType().GetProperties())
    {
        object val = prop.GetValue(parameters, null);

        var par = factory.Create<IDbDataParameter>();
        par.ExpectSet(p => p.ParameterName, prop.Name);
        par.ExpectSet(p => p.Value, val ?? DBNull.Value);
        pq.Enqueue(par.Object);

        parms.Expect(c => c.Add(par.Object)).Returns(0);
    }

    cmd.ExpectSet(c => c.CommandText, commandText);
    cmd.ExpectSet(c => c.CommandType, commandType);
    cmd.ExpectGet(c => c.Parameters).Returns(parms.Object);
    cmd.Expect(c => c.CreateParameter()).Returns(() => pq.Dequeue());
    cmd.Expect(c => c.Dispose());
    return cmd;
}

So if you have a stored procedure called “GetFooByID” and you expect to pass it an “@id” parameter with a value of 1, you simply construct your mock like this:

var cmd = mockFactory.CreateDbCommand("GetFooByID", CommandType.StoredProcedure, new { id = 1 });

… and then, of course, set up your expectations about how the command will be executed (presumably with an ExecuteReader in this scenario).

Note that is code is still using the “Expect” syntax in Moq rather than the new “Setup” syntax, so your mileage may vary. It’s certainly made life easy for us when mocking ADO.NET commands.