Cześć #dotnet corowe świry, czy macie pomysł jak zmokować Automappera w unit testach (xunit)? Czy jest jakaś możliwość, żebym przekazał go przez DI z projektu, który zawiera web api?
@Niebieskowaty: @Myrten: Czegoś chyba nie rozumiem. Załóżmy, że mam klasę, które ma w konstrutorze IMapper mapper, jak za pomocą tego co napisał @Niebieskowaty przekazać IMapper do konstruktora. Dzięki za pomocą i wesołych świąt. Żeby każdy dzień był zielony w test explorerze. :D
@GaHee: Nie wstrzykujesz mappera do konstruktorów tylko traktujesz go jak statycznego singletona którego inicjalizujesz przed odpaleniem testów/aplikacji
@Myrten: Kurde, wszędzie gdzie nie spojrzę, wszyscy wykorzystują dobrodziejstwo built-in DI .AddAutoMapper() i wstrzykują przez konstruktor. Masz może jakiś fragment kodu z singletonem?
@GaHee: no możesz zmockować mappera, żeby zwracał zawsze to samo po wywołaniu jakiejś tam metody używając Moq czy innego frameworka do mocków. Ale czy to ma sens? Wydaje mi się, że lepiej będzie napisać test który sprawdza mappingi, a jak testujesz klasę która potrzebuje mappera to jej go daj
@Niebieskowaty: Przyjmijmy, że chce przetestować taką metodę:
public async Task> GetBooksForUserAsync(string userId, int pageSize, int pageNumber) { var user = await _context.Users.Include(u => u.Books).FirstOrDefaultAsync(u => u.Id.Equals(userId)); if (user == null) { throw new UserNoFoundException($"User {userId} no found."); }
var books = user.Books.Where(b => !b.IsDeleted);
var booksDto = mapper.Map, IEnumerable>(books); return new PagedList(booksDto.AsQueryable(), pageNumber, pageSize); }
Klasa, w której ta metoda się znajduje implementuje IMapper` i jest wstrzykiwane prze konstruktor. Mój problem
@GaHee: Jak twój kontener DI ma .AddAutoMapper() to sprawdź czy tam nie ma jakiś przeciążeń albo innych opcji pozwalających podać profil automapera i wtedy przy testach podmieniasz ten profil
@GaHee: no widzisz, czyli bazy danych też nie mockujesz jako tako tylko tworzysz specjalną wersję na testy. Z mapperem jest to samo, jeśli chciałbyś go zmockować to musiałbyś stworzyć mocki dla metod Map które zwrócą Ci określony obiekt, to droga do nikąd według mnie.
@Niebieskowaty: @Myrten: Dzięki za pomoc. @Niebieskowaty skorzystałem z twojej sugestii i sprawdziła się w stu procentach. Jeszcze muszę popracować nad tymi testami.
@GaHee pamietaj, ze kazdy framework ma atrybuty do metod ktore moga sie wykonywać przed każdym testem albo przed kazdym testfixture. Dzieki temu kod który będzie Ci sie powtarzal w każdym tescie możesz tam umieścić
@Niebieskowaty: Właśnie myślę o tym, żeby wydzielić, gdzieś ten kod odpowiedzialny za tworzenie InMemoryDb etc. Też nie do końca mi do gustu przypadł ten xUnit, chyba przyjemniejszy w odbiorze był nUnit.
@GaHee no ja w pracy używałem tylko nUnita więc nie mam zdania co do innych. A co do kodu to jest dużo możliwości żeby to ładnie uporządkować. W NUnicie sa SetUp i TearDown atrybuty chyba, masz jeszcze konstruktor klasy z testami który też może coś zrobić ;)
#programowanie #unittest #naukaprogramowania #csharp
Mapper.AssertConfigurationIsValid();
IMapper mapper
, jak za pomocą tego co napisał @Niebieskowaty przekazaćIMapper
do konstruktora. Dzięki za pomocą i wesołych świąt. Żeby każdy dzień był zielony w test explorerze. :DPrzyjmijmy, że chce przetestować taką metodę:
public async Task> GetBooksForUserAsync(string userId, int pageSize, int pageNumber)
{
var user = await _context.Users.Include(u => u.Books).FirstOrDefaultAsync(u => u.Id.Equals(userId));
if (user == null)
{
throw new UserNoFoundException($"User {userId} no found.");
}
var books = user.Books.Where(b => !b.IsDeleted);
var booksDto = mapper.Map, IEnumerable>(books);
return new PagedList(booksDto.AsQueryable(), pageNumber, pageSize);
}
IMapper` i jest wstrzykiwane prze konstruktor.Klasa, w której ta metoda się znajduje implementuje
Mój problem
Póki co, mam coś takiego: https://pastebin.com/vn7yN1tc
https://stackoverflow.com/a/43875874
Tutaj nawet człowiek z teamu automappera nie widzi sensu żeby go mockować :P W przygotowywaniu testu zrób kawałek kodu z tej dokumentacji http://docs.automapper.org/en/stable/Configuration.html
Oczywiście możesz użyć
@GaHee: no to zamiast tworzyć mock po prostu skonfiguruj tego mappera i go przekaż. :)