3

使用时,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> 方法。我究竟做错了什么?

4

2 回答 2

4

Query<T>是一种扩展方法。

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

然而,起订量不能模拟扩展方法。因此,要么模拟该扩展方法内部所做的事情,这将涉及必须检查Dapper 源代码

或者

将该功能封装在您控制并可以模拟的抽象后面。

于 2017-08-15T17:19:42.150 回答
2

我倾向于用我自己的对象来包装外部库,以使测试变得容易,语言也可以品味。此外,您将这些库中的潜在更改与包装对象隔离开来。此外,您可以快速将缓存等功能添加到您的方法中。但最重要的是,因为它与这个问题有关,你可以轻松地模拟它。

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...)
于 2017-08-17T13:14:53.037 回答