Biblioteka FluentAssertions
Na początek zapoznaj się, proszę z klasą ProductService.
public class ProductService
{
private readonly IProductValidator _productValidator;
public ProductService(IProductValidator productValidator)
{
_productValidator = productValidator;
Products = new List<Product>();
}
public IList<Product> Products { get; set; }
public void Add(Product product)
{
if (_productValidator.IsAvailable(product))
Products.Add(product);
}
}
Głównie interesuje nas tutaj metoda Add, która jeżeli produkt jest dostępny, to dodaje go do listy. Mamy już też napisany test do tej metody.
public class ProductServiceTests
{
public void Add_WhenProductIsAvailable_ShouldAddProductToTheList()
{
var product = new Product { Quantity = 1 };
var productService = new ProductService(new ProductValidator());
productService.Add(product);
Assert.AreEqual(1, productService.Products.Count);
}
}
Test przechodzi, wszystko jest w porządku, ale przyjrzyjmy się naszej asercji. Czy ona jest czytelna? Czy wiesz, jaki jest pierwszy parametr metody Assert.AreEqual? Czy wiesz, jaki jest drugi parametr? Czy kolejność na pewno jest dobra. Niestety nie jest to takie intuicyjne i często spotykałem się z testami, gdzie te parametry były podawane w odwrotnej kolejności.
Żebyśmy mieli lepsze porównanie, napiszmy ten sam test, ale używając assercji z biblioteki FluentAssertions. Aby to zrobić, najpierw trzeba zainstalować przez nugeta bibliotekę FluentAssertions. Wystarczy otworzyć "Manage Nuget Packages" dla projektu z testami i zainstalować bibliotekę FluentAssertions.
Następnie trzeba dodać using FluntAssertions w klasie z testami i możemy już używać płynnych assercji.
using FluentAssertions;
Spróbujmy teraz napisać ten sam test, ale używając assercji biblioteki FluentAssertions.
public class ProductServiceTests
{
public void Add_WhenProductIsAvailable_ShouldAddProductToTheList()
{
var product = new Product { Quantity = 1 };
var productService = new ProductService(new ProductValidator());
productService.Add(product);
Assert.AreEqual(1, productService.Products.Count);
}
[Test]
public void Add_WhenProductIsAvailable_ShouldAddProductToTheList_FluentAssertions()
{
var product = new Product { Quantity = 1 };
var productService = new ProductService(new ProductValidator());
productService.Add(product);
productService.Products.Count.Should().Be(1);
}
}
Stosując assercje FluentAssertions mamy mnóstwo metod, które ułatwiają nam pisanie asercji. Między innymi możemy użyć metod Should() Be(), tak jak to zrobiliśmy w naszym przypadku, ale też Should() BeGreaterThan(), BeLessThan(), NotBe() i wiele innych. Oczywiście w tym miejscu dla każdego typu są różne metody.
Porównując te 2 assercję:
Assert.AreEqual(1, productService.Products.Count);
productService.Products.Count.Should().Be(1);
Możemy zauważyć, że asercję pisane z użyciem metod rozszerzających biblioteki FluentAssertions są dużo bardziej czytelne i intuicyjne. Nie musimy tutaj się zastanawiać, co jest wartością oczekiwaną, a co wartością faktyczną. I to jest właśnie pierwsza zaleta tej biblioteki.
Oczywiście biblioteka FluentAssertions ma dużo różnych metod, z którymi należy się zapoznać, jednak jest to temat na osobny materiał, w tym chciałem Ci przedstawić tylko 2 najważniejsze zalety tej bibloteki.
Także druga zaleta to lepsze komunikaty, gdy nasze testy nie przechodzą. Zrobię teraz błąd w naszych testach i porównamy sobie komunikaty, jakie dostaniemy w obu przypadkach. Zmienię tylko dla obu testów wartość właściwości Quantity na 0.
public class ProductServiceTests
{
public void Add_WhenProductIsAvailable_ShouldAddProductToTheList()
{
var product = new Product { Quantity = 0 };
var productService = new ProductService(new ProductValidator());
productService.Add(product);
Assert.AreEqual(1, productService.Products.Count);
}
[Test]
public void Add_WhenProductIsAvailable_ShouldAddProductToTheList_FluentAssertions()
{
var product = new Product { Quantity = 0 };
var productService = new ProductService(new ProductValidator());
productService.Add(product);
productService.Products.Count.Should().Be(1);
}
}
Po uruchomieniu oba testy są czerwone, czyli nie przechodzą. Każdy z nich zwrócił inny komunikat.
Assert.AreEqual: "Expected: 1 But was: 0".
Fluent Assertions: "Expected productService.Products.Count to be 1, but found 0".
Jednak w przypadku FluentAssertions jest on dużo bardziej szczegółowy, od razu wiadomo, nawet nie znając tych testów, gdzie jest błąd i co poszło nie tak. Także wydaje mi się, że jest to duży plus. Ja ze swojej strony polecam Ci zapoznać się z biblioteką FluentAssertions, używam jej na co dzień i bardzo mi ułatwia w pisaniu dobrych i czytelnych testów jednostkowych.
Warto się zapoznać z dokumentacją tej biblioteki, gdzie znajdziesz opisy jak testować poszczególne scenariusze testowe.
PODSUMOWANIE
Tak wyglądają płynne assercje, pisane za pomocą biblioteki FluentAssertions. warto zapoznać się z dokumentacją tej biblioteki, w której znajdziesz szczegółowe opisy, jak dokładnie testować różne scenariusze testowe.
To wszystko na dzisiaj, do zobaczenia w kolejnym artykule.
Poprzedni artykuł - 7 Podstawowych Błędów Programistów Podczas Pisania Testów Jednostkowych.
Następny artykuł - Jak Wysyłać E-maile w C#? Prosta Implementacja Wysyłki Mailowej i Konfiguracja Konta Gmail.