簡體   English   中英

使用Moq時在Dapper方法上獲取NotSupportedException

[英]Getting NotSupportedException on Dapper method when using Moq

使用Moq我在下面得到此異常:

System.NotSupportedException: 'Expression references a method that does not belong to the mocked object: c => c.Query<MyClass>(It.IsAny<String>(), It.IsAny<Object>(), It.IsAny<IDbTransaction>(), It.IsAny<Boolean>(), It.IsAny<Nullable`1>(), (Nullable`1)It.IsAny<CommandType>())'

我的課:

public class MyClass
{
    public int Id {get; set;}
    public string Name {get; set;}
}

我實際的BI課。 我正在為這個課程使用Dapper

using Dapper;

//**
//**
//**
using (var con = _readRepository.CreateConnection())
{
    var query = "Select * FROM myTable"
    return con.Query<MyClass>(query, new { Skip = 0, Take = 10}, null, true, null, null);
}

我的單元測試:

var conMock = new Mock<IDbConnection>();

IEnumerable<MyClass> listModels = new List<MyClass>().AsEnumerable();

//The exception occurrs right here
conMock.Setup(c => c.Query<MyClass>(
        It.IsAny<string>(),
        It.IsAny<object>(),
        It.IsAny<IDbTransaction>(),
        It.IsAny<bool>(),
        It.IsAny<int?>(),
        It.IsAny<CommandType>()
))
.Returns(() => listModels);

//System.NotSupportedException: 'Expression references a method that does not belong to the mocked object: c => c.Query<MyClass>(It.IsAny<String>(), It.IsAny<Object>(), It.IsAny<IDbTransaction>(), It.IsAny<Boolean>(), It.IsAny<Nullable`1>(), (Nullable`1)It.IsAny<CommandType>())'

我只想做的是模擬Query<MyClass> 方法 我究竟做錯了什么?

Query<T>是擴展方法。

public static IEnumerable<T> Query<T>(
    this IDbConnection cnn, 
    string sql, 
    object param = null, 
    SqlTransaction transaction = null, 
    bool buffered = true
)

Moq不能模擬擴展方法。 因此,要么模擬在該擴展方法內部進行的操作,要么必須檢查Dapper源代碼

要么

將該功能封裝在您可以控制並可以模擬的抽象后面。

我傾向於將外部庫與自己的對象包裝在一起,以使測試變得容易和易於使用。 此外,您可以將這些庫中的潛在更改隔離到包裝對象中。 另外,您可以快速將諸如緩存之類的功能添加到您的方法中。 但最重要的是,因為它與此問題相關,所以您可以輕松地模擬它。

public interface IDatabase{

IDbConnection GetConnection();
IEnumerable<T> Query<T>(whatever you want here...exactly Dapper's parameters if necessary);

}

public class Database : IDatabase{
     //implement GetConnection() however you like...open it too!
     public IEnumerable<T> Query<T>(...parameters...){

     IEnumerable<T> query = null;
     using(conn = this.GetConnection()){
          query = conn.Query<T>()//dapper's implementation
     }
     return query;
   }
}

現在,您可以使用總控制來模擬IDatabase。

var mockDb = new Mock<IDatabase>();
mockDb.Setup(s=>s.Query(It.IsAny<>...whatever params...).Returns(...whatever you want to return...)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM