简体   繁体   中英

Moq.Dapper QueryAsync does not work with mocked transaction object

I am trying to test my repository method which uses QueryAsync() and it is under a transaction. So I am mocking IDbConnection as well as IDbTransaction. But when I run the test case it gives an error

"Unable to cast object of type 'Castle.Proxies.IDbTransactionProxy' to type 'System.Data.Common.DbTransaction'"

using System;
using Dapper;
using Moq;
using Moq.Dapper;
using System.Data;
using System.Data.Common;
using System.Linq;
using System.Collections.Generic;

public class Program
{
public class ComplexType
{
    public string StringProperty { get; set; }
    public int IntegerProperty { get; set; }
}


private static void TestMoqDapperExecuteAsyncIDbConnectionWithoutTransaction()
{
        var connection = new Mock<IDbConnection>();

        connection.SetupDapperAsync(c => c.QueryAsync<int>(It.IsAny<string>(), It.IsAny<object>(), It.IsAny<IDbTransaction>(), It.IsAny<int>(), It.IsAny<CommandType>()))
                  .ReturnsAsync(new List<int>
        {
            5
        });

        var result = connection.Object
                               .QueryAsync<int>("")
                               .GetAwaiter()
                               .GetResult();

    Console.WriteLine(string.Format(" Test without transaction {0}", result.Count() != 0 ? "PASSED" : "FAILED"));
}

private static void TestMoqDapperExecuteAsyncIDbConnectionWithTransaction()
{
        var connection = new Mock<IDbConnection>();
        var tran= new Mock<IDbTransaction>();

        connection.SetupDapperAsync(c => c.QueryAsync<int>(It.IsAny<string>(), It.IsAny<object>(), It.IsAny<IDbTransaction>(), It.IsAny<int>(), It.IsAny<CommandType>()))
                  .ReturnsAsync(new List<int>
        {
            5
        });

        var result = connection.Object
                               .QueryAsync<int>("",null,tran.Object)
                               .GetAwaiter()
                               .GetResult();

    Console.WriteLine(string.Format("Test  with transaction {0}", result.Count() != 0 ? "PASSED" : "FAILED"));
}

public static void Main()
{   
    TestMoqDapperExecuteAsyncIDbConnectionWithoutTransaction();
    TestMoqDapperExecuteAsyncIDbConnectionWithTransaction();
}

}

You can also run it on fiddle to reproduce same issue https://dotnetfiddle.net/40lMbh

Based on the exception message it appears the QueryAsync extension method makes use of DbTransaction

So use the abstract DbTransaction instead and it will pass.

TestMoqDapperExecuteAsyncIDbConnectionWithTransaction()

//...

var tran = new Mock<DbTransaction>(); //<--Note abstract class instead of interface

//...

Tested it on the provided fiddle and it works.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM