So che ci sono diverse domande simili alle mie.Dapper test unitario con query in linea
butI non credo sia di domanda di cui sopra ha una risposta chiara che si adattano la mia richiesta.
In questo momento sviluppo un nuovo progetto WebAPI e divido tra il progetto WebAPI e la tecnologia DataAccess. Non ho problemi a testare il controller per WebAPI dato che posso prendere in giro la classe di accesso ai dati.
Ma per la classe DataAccess che è una storia diversa, dal momento che sto usando Dapper con query inline in esso, sono un po 'confuso come posso testarlo usando Unit Test. Ho chiesto ad alcuni dei miei amici e preferiscono fare test di integrazione invece di Unit Test.
Quello che voglio sapere è, è possibile testare la classe DataAccess che usa Dapper e le query Inline in esso.
Diciamo che ho una classe come questo (questa è una classe repository generico, in quanto molti dei codici hanno query simili differenziarsi dal nome della tabella e di campo)
public abstract class Repository<T> : SyncTwoWayXI, IRepository<T> where T : IDatabaseTable
{
public virtual IResult<T> GetItem(String accountName, long id)
{
if (id <= 0) return null;
SqlBuilder builder = new SqlBuilder();
var query = builder.AddTemplate("SELECT /**select**/ /**from**/ /**where**/");
builder.Select(string.Join(",", typeof(T).GetProperties().Where(p => p.CustomAttributes.All(a => a.AttributeType != typeof(SqlMapperExtensions.DapperIgnore))).Select(p => p.Name)));
builder.From(typeof(T).Name);
builder.Where("id = @id", new { id });
builder.Where("accountID = @accountID", new { accountID = accountName });
builder.Where("state != 'DELETED'");
var result = new Result<T>();
var queryResult = sqlConn.Query<T>(query.RawSql, query.Parameters);
if (queryResult == null || !queryResult.Any())
{
result.Message = "No Data Found";
return result;
}
result = new Result<T>(queryResult.ElementAt(0));
return result;
}
// Code for Create, Update and Delete
}
e l'implementazione di codice di cui sopra è come
public class ProductIndex: IDatabaseTable
{
[SqlMapperExtensions.DapperKey]
public Int64 id { get; set; }
public string accountID { get; set; }
public string userID { get; set; }
public string deviceID { get; set; }
public string deviceName { get; set; }
public Int64 transactionID { get; set; }
public string state { get; set; }
public DateTime lastUpdated { get; set; }
public string code { get; set; }
public string description { get; set; }
public float rate { get; set; }
public string taxable { get; set; }
public float cost { get; set; }
public string category { get; set; }
public int? type { get; set; }
}
public class ProductsRepository : Repository<ProductIndex>
{
// ..override Create, Update, Delete method
}
Solo una cosa, la fabbrica non è necessario ottenere un'astrazione di 'IDbConnection' (è già un'interfaccia), ma essere in grado di costruire nuove connessioni all'interno del repository. Se non è necessario (e probabilmente non è necessario creare più di una connessione nel contesto di una richiesta API Web) è possibile passare direttamente 'IDbConnection' al repository. –
@IgnacioCalvo Abbiamo bisogno di più di una connessione allo stesso tempo, ad es. quando si eseguono query asincrone che possono essere eseguite in parallelo. – Mikhail