Mocking DbCommand

3 posts, 0 answers
  1. miksh
    miksh avatar
    275 posts
    Member since:
    Nov 2006

    Posted 10 Sep 2013 Link to this post

    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. Stefan
    Admin
    Stefan avatar
    198 posts

    Posted 11 Sep 2013 Link to this post

    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.
  3. DevCraft R3 2016 release webinar banner
  4. miksh
    miksh avatar
    275 posts
    Member since:
    Nov 2006

    Posted 11 Sep 2013 Link to this post

    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.
Back to Top