Search code examples
c#unit-testingmoqdappernotsupportedexception

Getting NotSupportedException on Dapper method when using Moq


When using Moq I'm getting this exception below:

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

My class:

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

My actual BI class. I'm using Dapper for this class

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

My Unit Test:

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

What I'm only trying to do is to mock Query<MyClass> method. What am I doing wrong?


Solution

  • Query<T> is an extension method.

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

    Moq however can't mock extension methods. So either mock what is done internally in that extension method, which would involve having to go inspect the Dapper source code.

    or

    encapsulate that functionality behind an abstraction you control and can mock.