2015-04-21 18 views
6

Nawet po wdrożeniu Repository wzór abstrahować warstwę dostępu do danych (Eloquent ORM), kiedy robisz coś takiego:TDD oraz wykorzystanie widoków w laravel 5

$students = StudentRepository::all(); 
return view('students.index', ['students' => $students]); 

skończyć wysyłanie OSOBĄ \Eloquent\Model podklasa lub Eloquent\Collection do view.

Oznacza to, że jeśli Twój widok próbuje wykonać lazy-loading i uruchamiasz testy przypadków na serwerze CI, to nastąpi awaria z powodu braku połączenia z bazą danych.

Ten problem prowadzi do następujących rozwiązań:

  1. Kpisz bezpośrednio Eloquent podklasy w badaniach, tak, że gdy próbuje leniwy obciążenia, można ustawić wartość zwracaną
  2. implementować interfejsy dla każdego modelować i wiązać je za pomocą laravel's IoC.

Wady za to 2 opcji byłoby:

Dla opcji 1: Jeśli kończy się szyderczy wymowny od wyników badań, to jaki jest sens wdrożenia wzoru repozytorium (co wydaje się być bardzo popularny ze względu na "elastyczność", jeśli musisz zmienić Eloquent na inną ORM), ponieważ będziesz musiał ponownie napisać swoje testy.

Dla opcji 2: Jeśli piszesz interfejsy dla każdego Eloquent\Model, jedyne co musisz zrobić, to napisać dodatkowy kod dla setterów i pobierających.

Jeśli to daleko Wciąż jestem na właściwej ścieżce, opcja 2 byłby najlepszy wybórale nie ma absolutnie pojedynczą nić lub informacji dotyczących abstrahując Eloquent\Model do interfaces drwić połączeń wykonanych przez widzenia, które są albo lazy-loaded lub tylko properties.

Dlaczego tak jest? Czy czegoś nie widzę? może testy powinny zakończyć się przed renderowaniem widoku (a $this->assertViewHas($variable) jest bezcelowe)? może istnieje sposób, aby zignorować awarie, gdy występuje w widoku? może tylko ludzie testują kontrolery JSON API?

+1

Nasze testy zakończą się migracje/nasiona na bazie danych SQLite w pamięci, dzięki czemu można korzystać z pełnej funkcjonalności modelu. – ceejayoz

+0

Brzmi jak dobre rozwiązanie do testów integracyjnych. Czy jest to bardziej zalecane niż po prostu przeprowadzanie testów jednostkowych? –

+0

Preferuję to, ponieważ pozwala nam przetestować rzeczywistą funkcjonalność, a nie pozorowane wersje tego. Po prostu wykonujemy 'Artisan :: call ('migrate');' w podstawowej funkcji 'setup()' klasy 'TestCase' i użyj' 'database '=>': memory: '' w konfiguracji bazy SQLite. – ceejayoz

Odpowiedz

1

Czy to ptak? Czy to samolot? Nie, to rzadko używana i ledwo udokumentowana klasa Laravel Fluent na ratunek!

Klasa Fluent pozwala emulować wszystkie funkcje modelu lub innej klasy abstrakcyjnej z atrybutami, ale bez przenoszenia wagi lub zależności samej klasy modelu. Jest bardzo podobny do klas, które możesz budować jako klasy jednostek, gdy używasz narzędzia odwzorowującego dane, takiego jak Doctrine zamiast Eloquent Laravel.

płynnie obiekt może być zbudowany przez zapewnienie tablicę atrybutów jak klucz => par wartości tak:

$myobject = new Fluent(['id' => 666]); 

Można uzyskać dostęp do atrybutów za pomocą magicznych ustawiające i pobierające niczym obiektu modelu:

$myobject->id = 999; 
$myId = $myobject->id; 

a ponadto, ponieważ klasa Laravel Model ma właściwości Arrayable i ma funkcję toArray(), możesz użyć tych metod do utworzenia obiektu Fluent.

$myobject = new Fluent($mydatamodel->toArray()); 

Używając biegle w repozytorium klas można usunąć zależność od modelu laravel obiekty ze swoich poglądów, ale nadal mają wygodę magicznych ustawiające i pochłaniacze. Oczywiście jest trochę więcej gier jiggery w podejmowaniu wyników MyModel :: all() i zamienianiu tego w szereg Fluentów, ale w moim przypadku napisałem cechę, żeby to zrobić i dołączyć do moich modeli. Dodałem także cechę do wypełnienia modelu bezpośrednio od Fluent, ale to ćwiczenie pozostawione czytelnikowi.

http://laravel.com/api/5.1/Illuminate/Support/Fluent.html