Wiem, że jest kilka pytań podobnych do moich.Testowanie urządzenia z zapytaniami śródliniowymi
BUTI nie sądzę oba powyższe pytanie ma jasnej odpowiedzi, które pasują do mojego wymóg.
Teraz opracowuję nowy projekt WebAPI i dzielę go między projekt WebAPI i technologię DataAccess. Nie mam problemu z testowaniem kontrolera WebAPI, ponieważ mogę kpić z klasy dostępu do danych.
Ale dla klasy DataAccess są różne historie, ponieważ używam Dappera z wbudowanymi zapytaniami, jestem trochę zakłopotany, jak mogę przetestować to używając Testu Jednostki. Poprosiłem niektórych z moich znajomych i wolą wykonać test integracji zamiast testu jednostkowego.
Co chcę wiedzieć, czy możliwe jest przetestowanie klasy DataAccess, która używa w niej zapytań Dapper i Inline.
Powiedzmy mam klasy jak poniżej (jest to ogólna klasa repozytorium, ponieważ wiele z kodów mają podobne zapytania odróżnienia od nazwy tabeli i pola)
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
}
i wdrożenie do powyższego kodu jest jak
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
}
tylko jedna rzecz, fabryka nie jest konieczne, aby uzyskać abstrakcję 'IDbConnection' (jest to już interfejs), ale aby móc budować nowe połączenia wewnątrz repozytorium. Jeśli tego nie potrzebujesz (i prawdopodobnie nie będziesz musiał tworzyć więcej niż jednego połączenia w kontekście żądania Web API), możesz bezpośrednio przekazać "IDbConnection" do repozytorium. –
@IgnacioCalvo Potrzebujemy więcej niż jednego połączenia w tym samym czasie, np. podczas wykonywania zapytań asynchronicznych, które mogą działać równolegle. – Mikhail