This is a migrated thread and some comments may be shown as answers.

Mocking DbCommand

2 Answers 713 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
miksh
Top achievements
Rank 1
Iron
miksh asked on 10 Sep 2013, 04:52 PM
I need to mock any DbCommand calls to the specific sproc. I tried mocking
var cmd = Mock.CreateLike<System.Data.IDbCommand>(c => c.CommandText == "dbo.GetStartTime");
Mock.Arrange(() => cmd.ExecuteScalar())
    .Returns("10:00");

for the code below but I doesn't work. How can I achieve it?
private static string LoadFromDatabase(DateTime date)
{
    // create EntLib database object
 
    using (DbCommand cmd = db.GetStoredProcCommand("dbo.GetStartTime"))
    {
        db.AddInParameter(cmd, "DateToCheck", DbType.Date, date.Date);
        var startTime = db.ExecuteScalar(cmd);
 
        if (startTime == null || startTime == DBNull.Value)
            return null;
        else
            return startTime;
    }
}

2 Answers, 1 is accepted

Sort by
0
Stefan
Telerik team
answered on 11 Sep 2013, 09:50 AM
Hi Michael,

As I understand it, you want to execute some mock logic predicated on the properties of the instance on which a method was called. You also want that mock logic to execute on every instance of a given type.

In the next JustMock internal build, there will be a new feature that allows you to write Returns() clauses that can operate on the instance itself, rather than just the arguments.

Your arrange would then look like this:
var mock = Mock.Create<SqlDbCommand>();
Mock.Arrange(() => mock.ExecuteScalar())
    .IgnoreInstance()
    .Returns((IDbCommand @this) =>
        {
            if (@this.CommandText == "dbo.GetStartTime")
                return "10:00";
            else
                return null;
        });
By making an arrange with the IgnoreInstance() clause, you'll then be able to access the concrete instance in the delegate passed to returns. Inside the delegate you'll be able to implement the custom logic that relates the CommandText to the return value. What you won't be able to do is call the original implementation of ExecuteScalar - JustMock still doesn't support this.

Also, note that you must call Mock.Create<T>() for the concrete type of ADO.NET provider you use, e.g. SqlDbCommand. If you don't then interception for this type will not be enabled and you'll miss calls to methods declared on that type. It is not enough to call just Mock.Create<IDbCommand>().

I hope the above solution will prove useful and sufficient. If it doesn't fulfill all your testing needs, or have additional comments, then please write us back.

Regards,
Stefan
Telerik
Share what you think about JustTrace & JustMock with us, so we can become even better! You can use the built-in feedback tool inside JustTrace, our forums, or our JustTrace or JustMock portals.
0
miksh
Top achievements
Rank 1
Iron
answered on 11 Sep 2013, 06:15 PM
Thanks for detailed reply. I'm looking forward for the exciting features in the new release. Meanwhile, i'll try to reconsider my approach and mock the my class private method which calls db - hope it would be easier.
Tags
General Discussions
Asked by
miksh
Top achievements
Rank 1
Iron
Answers by
Stefan
Telerik team
miksh
Top achievements
Rank 1
Iron
Share this question
or