TDD and Using Views in Laravel 5

Even after implementing the repository template to abstract the data access level (Eloquent ORM) when you do something like:

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

You end up sending a subclass of \Eloquent\Model or Eloquent\Collection to the view .

This means that if your view tries to perform lazy loading and you run tests on the CI server, this may lead to a crash due to the lack of a database connection.

This problem leads to the following solutions:

  • You mock the Eloquent subclasses directly in your tests so that when you try to lazy load you can set the return value
  • You implement interfaces for each model and bind them using laravel IoC .

The disadvantages for these two options are:

For option 1: If you finish mocking Eloquent in your tests, then what's the point of implementing a repository template (which seems to be very popular because of its “flexibility” if you need to change from Eloquent to another ORM), since you have to rewrite your tests too.

For option 2: If you are writing interfaces for each Eloquent\Model , you only need to write additional code for setters and getters.

If so far I'm still on the right track, option 2 would be a better choice , but there is absolutely no thread or information about abstracting Eloquent\Model in interfaces to make fun of the calls made by the view, which are either lazy-loaded or just properties .

So why is that? Am I not seeing something? perhaps tests should exit before rendering the view (and $this->assertViewHas($variable) pointless)? maybe there is a way to ignore crashes when this happens in a view? maybe only people unit test JSON API controllers?

+6
source share
1 answer

Is it a bird? This is a plane? No, this is the rarely used and barely documented Laravel Fluent class for salvation!

The Fluent class allows you to emulate all the functionality of a model or other abstract class with attributes, but without transferring the weight or dependencies of the model class itself. This is very similar to classes that you could create as entity classes when you use an ORM data map, such as Doctrine, instead of Laravel Rloquent.

A A free object can be created by providing an array of attributes in the form of keys => values ​​of such pairs:

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

You can access attributes using magicians and getters, just like for a model object:

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

and besides, since the Laravel model class is Arrayable and has a toArray () function, you can use these methods to create your Fluent object.

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

Freely using your repository classes, you can remove the dependence on Laravel model objects from your views, but at the same time there are still the convenience of setup wizards and getters. Of course, there are a bit more jiggery-pokery that take the results of MyModel :: all () and turn this into an Fluents array, but in my case, I wrote a dash to do this and bound it to my models. I also added a line to populate the model directly from Fluent, but this exercise was left to the reader.

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

+1
source

Source: https://habr.com/ru/post/985633/


All Articles