Wpis z mikrobloga

Hejka mam pytanie. Piszę test jednostkowy w xunity handlera, który usuwa rekord zmieniając status.Jak mam zrobić mocka dbcontext aby przetestować handler z metodą Attach(), ponieważ obecnie dla mocka ctx zwraca nulla. Natomiast jak zrobię ctx.Departments.Find() to zwraca poprawny rekord i potem mogę użyć Remove.

var depState = ctx.Departments.Attach(dep);
depState.State = EntityState.Deleted;
ctx.SaveChangesAsync

#dotnet #csharp #programowanie #entityframework
  • 14
@MroczekBall3D: no mam wartości ustawione dla tego dbSet ale tak jak mówie dla Attach jest null natomiast dla Find działa ok.Tak tworzę moq

var fixture = new Fixture();
var departments= new List
{
fixture.Create(),
fixture.Create(),
}.AsQueryable();
;
var mockDbSet = ServiceTestsHelper.GetMockDbSet(departments);
var ctx = new Mock();
ctx.Setup(c => c.Departments).Returns(mockDbSet);
@smalczyk1: to co testujesz powinno być testem integracyjnym aplikacja - baza na działającej infrastrukturze. Testowanie tego mockując zależność od DB boli na co sam zwracasz uwagę - jakieś to takie, dziwne, trudne, nienaturalne.
Twój test tak naprawdę nie daje Ci żadnej pewności, że twój kod dobrze działa.
1. Sprawdzasz czy Attach działa? Do tego testy napisali twórcy EFa.
2. Sprawdzasz czy można przypisać "Deleted" do State? Jak wyżej.
3. Sprawdzasz czy
@MikelThief: Chciałem przetestować czy handler zwraca poprawny wynik patern CQRS.Czyli nie powinienm pisać testu dla handlera ? Tylko integracyjny najlepiej od endpointa deletete do handlera ?

Co masz na myśli wpspółpraca Ef z bazą? Chodzi,żeby napisać test który sprawdza czy jest po pprostu połaczenie pomiędzy apką a bazą?
@smalczyk1: W skrócie, na podstawie tego co napisałeś, wydaje się że wystarczy Ci jeden test integracyjny gdzie usuniesz jakiś konkretny resource i w tym samym teście sprawdzisz że go już tam nie ma (i zrobisz to wołając swoją działającą aplikację, która gada do działającej bazy danych).
Test integracyjny pokryje Ci działanie handlera i komunikację aplikacja-baza w tym konkretnym przypadku.

W bardzo wielkim skrócie:
1. unit testy najlepiej nadają się do sprawdzania
@MikelThief no dobrze to mogę napisać test integracyjny od cotrolera do handlera i sprawdzić result czyli czy akacja na bazie się udała.Tylko,że tak czy siak wywali się handlarze bo nie wiem jak zmokować bazę żeby attach nie zwrócił null.Czy bazę zamiast mocka robić metodą in memory?
@smalczyk1: Nie sprawdzasz czy akcja na bazie się udała - to sprawdzili już twórcy EF Core i nie ma sensu żebyś testował to w swojej aplikacji. Kolega wyżej opisał Ci bardzo dobrze, że powinieneś jedynie sprawdzić czy po wykonaniu akcji stan bazy jest zgodny z oczekiwanym stanem (pobrać ten obiekt i zrobić na nim asercję).

Szukaj w google pod hasłem ef core integration tests np.
https://www.thinktecture.com/en/entity-framework-core/isolation-of-integration-tests-in-2-1/

U mnie w projekcie to
@Niebieskowaty ok czyli dla delete powinienem przykładowo w tym transaction scope wywołać akcje add z controlera a potem delete i sprawdzić czy rekord został usunięty .

Tylko sprawdzę bo wydaje mi się że i tak mi się nie uda go usunąć bo attach zwróci null i nie będę mógł zmienić wtedy state i handler rzuci exeption i test będzie failed.Ale jeszcze sprawdzę
@smalczyk1: dokładnie tak. W sekcji Arrange wołasz prawdziwy (nie zmockowany) kontekst który używa prawdziwej bazy (albo chociaż in memory db). Dodajesz sobie itema, zapisujesz zmiany, później wołasz akcję delete w sekcji Act i w sekcji Arrange sprawdzasz czy pobranie itema z dbcontextu nie zwróci niczego
@smalczyk1: no i jeszcze warto wziąć pod uwagę aspekt izolacji testów. Najlepiej żeby każdy fixture miał swoją bazkę, u nas rozwiązujemy to w taki sposób, że tworzymy bazę z losowym guidem doklejonym do nazwy, a na koniec testu ją usuwamy