Obteniendo NotSupportedException en el método Dapper al usar Moq

c# dapper moq notsupportedexception unit-testing

Pregunta

Cuando uso Moq obtengo esta excepción a continuación:

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>())'

Mi clase:

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

Mi clase de BI real. Estoy usando Dapper para esta clase

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);
}

Mi prueba unitaria:

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>())'

Lo que intento hacer es Query<MyClass> método Query<MyClass> . ¿Qué estoy haciendo mal?

Respuesta aceptada

Query<T> es un método de extensión.

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

Sin embargo, Moq no puede burlarse de los métodos de extensión. Entonces, o bien simulan lo que se hace internamente en ese método de extensión, lo que implicaría tener que inspeccionar el código fuente de Dapper .

o

encapsular esa funcionalidad detrás de una abstracción que controlas y puedes simular.


Respuesta popular

Tiendo a envolver bibliotecas externas con mis propios objetos para facilitar las pruebas y el lenguaje a gusto. Además, aísla los cambios potenciales en esas bibliotecas en el objeto de envoltura. Además, puede agregar rápidamente funciones como el almacenamiento en caché de sus métodos. Pero lo más importante es que se puede relacionar fácilmente con esta pregunta.

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;
   }
}

Ahora puedes simular tu IDatabase con control total.

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


Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué