Unit Testing Dapper with Inline Queries

前端 未结 3 1248
深忆病人
深忆病人 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:35

    Here is our approach:

    1. First of all, you need to have an abstraction on top of IDbConnection to be able to mock it:

      public interface IDatabaseConnectionFactory
      {
          IDbConnection GetConnection();
      }
      
    2. Your repository would get the connection from this factory and execute the Dapper query on it:

      public class ProductRepository
      {
          private readonly IDatabaseConnectionFactory connectionFactory;
      
          public ProductRepository(IDatabaseConnectionFactory connectionFactory)
          {
              this.connectionFactory = connectionFactory;
          }
      
          public Task> GetAll()
          {
              return this.connectionFactory.GetConnection().QueryAsync(
                  "select * from Product");
          }
      }
      
    3. Your test would create an in-memory database with some sample rows and check how the repository retrieves them:

      [Test]
      public async Task QueryTest()
      {
          // Arrange
          var products = new List
          {
              new Product { ... },
              new Product { ... }
          };
          var db = new InMemoryDatabase();
          db.Insert(products);
          connectionFactoryMock.Setup(c => c.GetConnection()).Returns(db.OpenConnection());
      
          // Act
          var result = await new ProductRepository(connectionFactoryMock.Object).GetAll();
      
          // Assert
          result.ShouldBeEquivalentTo(products);
      }
      
    4. I guess there are multiple ways to implement such in-memory database; we used OrmLite on top of SQLite database:

      public class InMemoryDatabase
      {
          private readonly OrmLiteConnectionFactory dbFactory = new OrmLiteConnectionFactory(":memory:", SqliteOrmLiteDialectProvider.Instance);
      
          public IDbConnection OpenConnection() => this.dbFactory.OpenDbConnection();
      
          public void Insert(IEnumerable items)
          {
              using (var db = this.OpenConnection())
              {
                  db.CreateTableIfNotExists();
                  foreach (var item in items)
                  {
                      db.Insert(item);
                  }
              }
          }
      }
      

提交回复
热议问题