After reading a few tutorials and mostly watching videos on Laracasts
, I was considering adding an abstraction layer in my website using Repositories
which would be injected in my Controllers
through an interface. The Repositories
are there to abstract how the Model
is retrieved and hide some business logic. Using the Bind
method available in Laravel
, this seemed super easy and convenient.
This sounds super interesting to add unit tests
to a project, but I fail to understand how the Model
should be handled.
For example, let's say we're trying to hide the good old User
model behind a repository, by creating:
interface UserRepositoryInterface {
public function getAll();
// ...
}
Then, to support the standard User
model provided by Laravel, defined as:
class User extends Eloquent implements UserInterface, RemindableInterface {
// ...
}
We create an Eloquent
implementation of the UserRepositoryInterface
:
class EloquentUserRepository extends UserRepositoryInterface {
public function getAll() {
return User::all();
}
}
The part that I don't understand is that now, the Repository
doesn't return a "generic" Model
, it returns an Eloquent
model! It doesn't make sense to me that other Repositories
should return the same type of Model
, and if it's not the case, what's the point of having Repositories
if there is no correlation at all between the Models
returned?
What then is the proper usage of the Repository
pattern within Laravel
?
Repositories
in Laravel
help keep controllers thin and dumb.
Controllers
get to handle any route or data parsing before handing to the repository, and returning data in proper formats.
Repositories
get to handle the models.
If you have both of these functions are in the same controller method, you have trouble determining if the issue is in the parsing of the data from the input, or the requesting of data from the model.
This separation allows use to make sure the controller
is handing appropriate data to the repository
. That the repository
is performing the appropriate validations and accessing the model
in the correct manner, and that all of these are returning data of the correct type.
The repositories returned model
can be tested for type using instanceof
:
public function testAllReturnsCollection()
{
$collection = $this->machineRepository->all();
$this->assertTrue($collection instanceof \Illuminate\Database\Eloquent\Collection);
}
public function testFindReturnsMachine()
{
$model = $this->machineRepository->find($this->machineId);
$this->assertTrue($model instanceof Machine);
}
This type of testing can also be done with Mocking
, but when working with models I prefer to use a test database.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.