Wprowadzenie

Osoby śledzące regularnie moje wpisy wiedzą, że ostatnio większość swojego czasu w pracy poświęcam na technologie związane z interfejsem użytkownika. Związane jest to z pracą polegającą na przygotowaniu aplikacji spełniającej nowoczesne standardy programowania z istniejącą (w obecnym produkcie) logiką bizesową. Logika biznesowa zostaje przepisana całkowicie na mikroserwisy a członkowie mojego zespołu mają za zadanie przygotować kompletny interfejs użytkownika przy wykorzystaniu zestawu narzędzi jakim jest Oracle JET.

Tutaj niestety natrafiliśmy na pewne problemy. W idealnym świecie rozpoczynając pracę nad interfejsem użytkownika powinniśmy mieć dostęp do danych (API). Na bazie tych informacji dokonujemy odpowiedniego łączenia (bidnowania) otrzymanych danych z interfejsem użytkownika. Niestety, nie zawsze jest to możliwie...(z różnych przyczyn). Posiadając jednak podstawowe informacje, tj. przykładowy response jesteśmy w stanie przygotować własną implementację w postaci FakeAPI. Nie tracimy wówczas czasu czekając na w pełni działajacą logikę biznesową. Używając tzw. "kontraktów" jesteśmy w stanie przygotować po naszej stronie odpowiednie klasy wraz z przykładowymi danym oraz rozpocząć pracę po zainwestowaniu niewielkiej ilości czasu na taką implementację.

To będzie temat naszego artykułu – skupimy się na jednej z wielu bibliotek pozwalających na tworzenie przykładowego zestawu danych wraz z możliwością ich edycji oraz (co równie istotne) skorzystania z zaimplementowanych „gotowców".

GenFu

W jednym z poprzednich projektów korzystałem z biblioteki Bogus. Chciałem jednak skorzystać z czegoś innego (dla porównania) dlatego zdecydowałem się na GenFu.

Instalacja jest niezwykle prosta. Korzystając z konsoli zarządzania paczkami możemy skorzystać z poniższego polecenia:

install-package GenFu
Po poprawnej instalacji jesteśmy gotowi do pracy. Dodajmy jeszcze bibliotekę do przestrzeni nazw naszego przykładowego kontrolera i możemy przejść do przykładu:
using GenFu;

Generowanie danych

Załóżmy, że tworzymy nowy projekt, np. panel administracyjny naszego sklepu. Potrzebujemy zestawu danych takich jak imię, nazwisko, adres czy numer telefonu Klienta. Każdego z nich możemy opisać poniższą klasą:

public class Clients
{
    public int Id { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string PhoneNumber { get; set; }

    public string City { get; set; }

    public string Address { get; set; }

    public bool IsActive { get; set; }
}
Na potrzeby artykułu klasa została znacznie rozszerzona tak, aby pokazać możliwości tej biblioteki.

Samo użycie jest niezwykle proste. Jeżeli chcemy przygotować listę 10 Klientów możemy posłużyć się poniższym zapisem:

var clients = GenFu.GenFu.ListOf(10);
Wprowadzając drobne zmiany do świeżo utworzonego projektu w postaci:
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<Clients>> Get()
{
    var clients = GenFu.GenFu.ListOf<Clients>(10);

    return clients;
}
możemy zobaczyć przykładowe dane w formacie json:
[ 
   { 
      "id":32,
      "firstName":"Timothy",
      "lastName":"Sanchez",
      "phoneNumber":"(207) 210-9837",
      "city":"San RafaelCounty seat",
      "address":"5117 Duffield Street ",
      "isActive":true
   },
   { 
      "id":65,
      "firstName":"Makayla",
      "lastName":"Baker",
      "phoneNumber":"(423) 337-9762",
      "city":"Rancho Cordova",
      "address":"2777 44th Street ",
      "isActive":false
   },
   { 
      "id":14,
      "firstName":"Jennifer",
      "lastName":"Henderson",
      "phoneNumber":"(333) 734-6643",
      "city":"Sparks",
      "address":"8053 Orange Street ",
      "isActive":true
   },
   { 
      "id":2,
      "firstName":"Stephanie",
      "lastName":"Jackson",
      "phoneNumber":"(727) 669-2052",
      "city":"Santa Paula",
      "address":"8541 Snediker Avenue ",
      "isActive":false
   },
   { 
      "id":55,
      "firstName":"Anna",
      "lastName":"Robinson",
      "phoneNumber":"(440) 705-4228",
      "city":"Edgecliff Village",
      "address":"7102 Kings Hwy ",
      "isActive":true
   },
   { 
      "id":39,
      "firstName":"Mariah",
      "lastName":"Griffin",
      "phoneNumber":"(482) 543-2654",
      "city":"San Leandro",
      "address":"3332 General Lee Avenue ",
      "isActive":true
   },
   { 
      "id":18,
      "firstName":"Lauren",
      "lastName":"Chambers",
      "phoneNumber":"(288) 435-0570",
      "city":"Kingsland",
      "address":"5504 Atlantic Avenue ",
      "isActive":true
   },
   { 
      "id":74,
      "firstName":"Caroline",
      "lastName":"Campbell",
      "phoneNumber":"(321) 342-1940",
      "city":"Niagara Falls",
      "address":"5116 Kent Avenue ",
      "isActive":false
   },
   { 
      "id":74,
      "firstName":"Brian",
      "lastName":"Daeninck",
      "phoneNumber":"(601) 584-3019",
      "city":"San Ygnacio",
      "address":"7205 Lott Place ",
      "isActive":false
   },
   { 
      "id":44,
      "firstName":"Dylan",
      "lastName":"Kelly",
      "phoneNumber":"(450) 601-0417",
      "city":"Saint-Constant",
      "address":"1398 Strong Place ",
      "isActive":true
   }
]
Pierwsze co rzuca się w oczy to „jakość" danych. Imię, nazwisko, adres czy numer telefonu zawarte są w domyślnej implementacji biblioteki. Wyglądają niezwykle realistycznie a my nie musimy wprowadzać żadnych zmian. Co jeśli jednak takie dane nie są wystarczające dla Twojego projektu?

Możemy skorzystać z konfiguracji obiektu, który przygotowaliśmy. Jest ona również niezwykle prosta. Dodamy do naszej klasy wiek oraz adres email. Zakładamy, że użytkownicy będą starsi niż 17 lat a adres email będzie przyjmował określony format (na potrzeby prezentacji). Dodatkowo miasto będzie wybierane losowo z naszego własnego zakresu. W tym celu posłużymy się metodą Configure:

GenFu.GenFu.Configure<Clients>()
    .Fill(c => c.Age).WithinRange(18, 99)
    .Fill(c => c.EmailAddress, c => { return string.Format("{0}--{1}mymail.com", c.FirstName,c.LastName); })
    .Fill(c => c.City).WithRandom(new string[] {"Warszawa", "Gdynia", "Radom" });

// Pamiętajcie, że konfiguracja musi wystapić przed utworzeniem obiektu
var clients = GenFu.GenFu.ListOf<Clients>(10);
    
Efekt powyższej implementacji prezentuje się w następujący sposób:
[ 
   { 
      "id":86,
      "firstName":"Alexa",
      "lastName":"Gomes",
      "age":52,
      "emailAddress":"Alexa--Gomes@mymail.com",
      "phoneNumber":"(687) 213-0195",
      "city":"Gdynia",
      "address":"3795 Bridgewater Street ",
      "isActive":false
   },
   { 
      "id":48,
      "firstName":"Claire",
      "lastName":"Getzlaff",
      "age":75,
      "emailAddress":"Claire--Getzlaff@mymail.com",
      "phoneNumber":"(625) 445-2777",
      "city":"Radom",
      "address":"4291 Livingston Street ",
      "isActive":true
   },
   { 
      "id":63,
      "firstName":"Simon",
      "lastName":"Thomas",
      "age":29,
      "emailAddress":"Simon--Thomas@mymail.com",
      "phoneNumber":"(734) 784-7765",
      "city":"Warszawa",
      "address":"9365 Lamont Court ",
      "isActive":false
   },
   { 
      "id":15,
      "firstName":"Benjamin",
      "lastName":"Rogers",
      "age":58,
      "emailAddress":"Benjamin--Rogers@mymail.com",
      "phoneNumber":"(506) 256-2766",
      "city":"Warszawa",
      "address":"8197 Covert Street ",
      "isActive":false
   },
   { 
      "id":3,
      "firstName":"Rachel",
      "lastName":"Morris",
      "age":82,
      "emailAddress":"Rachel--Morris@mymail.com",
      "phoneNumber":"(298) 498-4098",
      "city":"Radom",
      "address":"5567 Central Avenue ",
      "isActive":true
   },
   { 
      "id":51,
      "firstName":"Claire",
      "lastName":"Brandzin",
      "age":44,
      "emailAddress":"Claire--Brandzin@mymail.com",
      "phoneNumber":"(758) 542-9765",
      "city":"Gdynia",
      "address":"8704 Crown Street ",
      "isActive":true
   },
   { 
      "id":26,
      "firstName":"Rebecca",
      "lastName":"Radcliff",
      "age":72,
      "emailAddress":"Rebecca--Radcliff@mymail.com",
      "phoneNumber":"(289) 411-2291",
      "city":"Gdynia",
      "address":"5582 Brighton 10th Lane ",
      "isActive":false
   },
   { 
      "id":39,
      "firstName":"Sammy",
      "lastName":"Mc Vicar",
      "age":63,
      "emailAddress":"Sammy--Mc Vicar@mymail.com",
      "phoneNumber":"(527) 769-3138",
      "city":"Gdynia",
      "address":"257 Middagh Street ",
      "isActive":false
   },
   { 
      "id":44,
      "firstName":"Samantha",
      "lastName":"Hall",
      "age":73,
      "emailAddress":"Samantha--Hall@mymail.com",
      "phoneNumber":"(251) 686-7879",
      "city":"Gdynia",
      "address":"6377 Boardwalk  ",
      "isActive":false
   },
   { 
      "id":73,
      "firstName":"William",
      "lastName":"Olsen",
      "age":90,
      "emailAddress":"William--Olsen@mymail.com",
      "phoneNumber":"(229) 345-8317",
      "city":"Gdynia",
      "address":"4127 Dinsmore Place ",
      "isActive":false
   }
]

Jak widzicie, proces instalacji, konfiguracji czy użycia dostępnych danych jest niezwykle prosty i intuicyjny.

Podsumowanie

Na zakończenie warto wspomnieć o dostępnych rozszerzeniach w zależności o typu konfigurowanej właściwości. Z pomocą przychodzi nam IntelliSense: Konfiguracja właściwości przy użyciu biblioteki GenFu

Mam nadzieję, że na przykładzie powyższego artykułu zobaczycie, że warto eksperytmentować z nowymi bibliotekami nawet jeżeli macie swoje ulubione, których używacie od dłuższego czasu.