Unit Testing Dapper with Inline Queries

前端 未结 3 1255
深忆病人
深忆病人 2021-01-31 19:56

I know there are several question similar to mine.

  • Dapper: Unit Testing SQL Queries
  • Testing Dapper Queries

butI don\'t think both of above

3条回答
  •  面向向阳花
    2021-01-31 20:26

    I would like add another perspective on this problem and a solution that takes a different approach to solving it.

    Dapper can be considered as a dependency on the repository class as it is an external codebase that we have no control over. Therefore testing it is not really in the realm of responsibility for Unit Testing (More in line with integration testing as you mentioned).

    With that said, we cannot really mock Dapper directly because it is really just an extension method set on the IDbConnection interface. We could mock all of the System.Data code until we get down to the IDbCommand where Dapper really does its work. That however would be a lot of work, and in most cases not worth the effort.

    We instead can create a simple IDapperCommandExecutor mock-able interface:

    
    public interface IDapperCommandExecutor
    {
        IDbConnection Connection { get; }
    
        T Query(string sql, object? parameters = null);
    
        // Add other Dapper Methods as required...
    }
    
    

    This interface then can simply be implemented with Dapper:

    
    public class DapperCommandExecutor : IDapperCommandExecutor
    {
        public DapperCommandExecutor(IDbConnection connection)
        {
            Connection = connection;
        }
    
        IDbConnection Connection { get; }
    
        T Query(string sql, object? parameters = null) 
            => Connection.QueryAsync(sql, parameters);
    
        // Add other Dapper Methods as required...
    }
    
    

    Then all you would have to do is change the following:

    var queryResult = sqlConn.Query(query.RawSql, query.Parameters);
    

    to

    var queryResult = commandExecutor.Query(query.RawSql, query.Parameters);
    

    Then in your testing, you can create a mocked Command Executor

    
    public class MockCommandExecutor : Mock
    {
    
        public MockCommandExecutor()
        {
            // Add mock code here...
        }
    
    }
    
    

    In summary, we do not need to test the Dapper library, it can, for unit testing, be mocked in. This mocked Dapper Command Executor will reduce the additional dependency requirement for an in-memory database and can reduce the complexity of your tests.

提交回复
热议问题