Pozostając OO i testowalne podczas pracy z bazą danych


16

Jakie są niektóre strategie OOP do pracy z bazą danych, ale testowania jednostki? Załóżmy, że mam klasę użytkownika, a moje środowisko produkcyjne działa przeciwko MySQL. Widzę kilka możliwych podejść, pokazanych tutaj za pomocą PHP:

  1. Przekaż źródło danych $ z interfejsami dla load()i save(), aby wyodrębnić źródło danych zaplecza. Podczas testowania przekaż inny magazyn danych.

    $ user = nowy użytkownik ($ mysql_data_source);
    $ user-> load ('bob');
    $ user-> setNickname („Robby”);
    $ user-> save ();
    
  2. Użyj fabryki, która uzyskuje dostęp do bazy danych i przekazuje wiersz wynikowy do konstruktora użytkownika. Podczas testowania ręcznie wygeneruj parametr $ row lub wyśmiewaj się z obiektu w UserFactory :: $ data_source. (Jak mogę zapisać zmiany w rekordzie?)

    class UserFactory {
        static $data_source;
    
        public static function fetch( $username ) {
            $row = self::$data_source->get( [params] );
    
            $user = new User( $row );
            return $user;
        }
    }
    

Mam obok siebie Wzory Projektowe i Czysty Kod , ale staram się znaleźć odpowiednie koncepcje.


Odpowiedzi:


11

Tak więc, co chcesz wziąć pod uwagę, to wzorce architektury aplikacji korporacyjnych Martina Fowlersa (tutaj również udostępnia katalog na swojej stronie internetowej ).

W nim opisuje kilka wzorców abstrakcji dostępu do danych. Pierwsze podejście, które opisujesz, to Active Record . Twoje drugie podejście jest podobne do Table Data Gateway .

Jeszcze lepszym rozwiązaniem jest użycie O / RM, aby wyeliminować potrzebę ręcznego pisania kodu dostępu do danych. Nie korzystałem z PHP, ponieważ martwiliśmy się o Y2K, ale wikipedia ma dla ciebie listę opcji . Nie wiem jednak, czy są jakieś dobre. Mogę jednak powiedzieć kilka rzeczy, których należy szukać w O / RM:

  • Ignorancja trwałości : operacja O / RM nie powinna wymuszać na obiektach biznesowych korzystania z określonego interfejsu / klasy w celu uczestnictwa w strategii dostępu do danych.
  • Mapowanie relacji : Powinieneś być w stanie mapować relacje między swoimi obiektami (klient ma zamówienia, zamówienia mają elementy zamówienia, elementy zamówienia mają produkt itp.)
  • Mapowanie hierarchiczne : Powinieneś mieć możliwość mapowania hierarchii klas do bazy danych.
  • Obsługa składni / kryteriów zapytania : Powinieneś być w stanie utworzyć zapytanie w czasie wykonywania w odniesieniu do obiektów, a nie bazy danych, a O / RM powinien przetłumaczyć i uruchomić zapytanie w bazie danych. Dodatkowe punkty, jeśli zapytanie jest łańcuchem o silnym typie, a nie łańcuchem.

Należy wziąć pod uwagę inne czynniki, ale są to jedne z najważniejszych. Mam nadzieję że to pomoże.


6

IMHO zależy od tego, co chcesz przetestować, jeśli chcesz przetestować logikę biznesową w jednostce, powinieneś udaremnić / wyśmiać ( Martin Fowler ) dostęp do danych, aby Twoja pierwsza sugestia była dobrym początkiem. To pytanie o przepełnienie stosu daje dobry przykład w języku C # (próbowałem znaleźć próbki PHP, ale nie znalazłem).

Jeśli chcesz przetestować dostęp do danych sam w sobie, nie nazywa się to już testowaniem jednostkowym, ale testowaniem integracyjnym. Przeczytaj tutaj ogólne wskazówki, to pytanie o przepełnieniu stosu zawiera również kilka interesujących linków.

Jeśli chcesz przetestować logikę procedury składowanej w swojej bazie danych, spójrz na xUnit TestPattern

Mam nadzieję że to pomoże


2

To niekoniecznie jest natychmiastowa pomocna odpowiedź, ale jeśli naprawdę martwisz się o testowanie bazy danych, powinieneś przyjrzeć się, jak to się robi w Ruby on Rails. O ile mi wiadomo, nikt nie omawiał tego tematu lepiej ani bardziej intuicyjnie.


2
Ruby on Rails domyślnie implementuje wzorzec Active Record. Może również podać link: en.wikipedia.org/wiki/Active_record_pattern
Spoike

0

Poleciłem Ci sprawdzenie rozwiązania Symfony Framework dla tego rodzaju problemu. Symfony to framework OO php z testami funkcjonalnymi.

Oto link , użyli czegoś takiego, o czym myślisz.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.