I know there are several question similar to mine.
butI don\'t think both of above
Here is our approach:
First of all, you need to have an abstraction on top of IDbConnection
to be able to mock it:
public interface IDatabaseConnectionFactory
{
IDbConnection GetConnection();
}
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");
}
}
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);
}
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);
}
}
}
}