我目前正在尝试在 Laravel 中实现存储库模式。
我有一个接口,它声明了成为有效存储库所需的最少方法。
<?php
namespace App\Repositories;
interface RepositoryInterface
{
public function all();
public function create($entity);
public function update($entity);
public function find($id);
public function delete($entity);
}
我有一个抽象类,它代表我的存储库上的接口方法,如下所示:
namespace App\Repositories;
use DB;
abstract class DbRepository
{
public function all()
{
return DB::table($this->tableName)->get();
}
public function create($user)
{
return $user->save();
}
public function update($user)
{
return $user->update();
}
public function find($id)
{
return DB::table($this->tableName)->where('id', $id)->first();
}
public function delete($user)
{
return $user->delete();
}
}
UserRepository
实现接口并从抽象类继承的an如下:
namespace App\Repositories;
use App\Models\User;
class UserRepository extends DbRepository implements RepositoryInterface
{
public $tableName;
public function __construct($tableName = 'users')
{
$this->tableName = $tableName;
}
/**
* Override the parent find method, as we want to return an instance of App\Models\User instead of stdClass
* @param $id
* @return mixed
*/
public function find($id)
{
return User::where('id', $id)->first();
}
}
上面的一切工作正常,我的单元测试通过了。但是,我决定将当前数据库表作为存储库的抽象实现的属性来保存会很好,因此我将类重构为如下所示:
abstract class DbRepository implements RepositoryInterface
{
private $table;
public function __construct()
{
$this->table = DB::table($this->tableName);
}
public function all()
{
return $this->table->get();
}
# etc, etc...
然后确保从 Repository 的构造函数中调用了抽象类的构造函数:
public function __construct($tableName = 'users')
{
$this->tableName = $tableName;
parent::__construct();
}
Error: Class 'DB' not found
执行此操作后,我收到以下错误,在运行 PhpUnit 时无法修复。
我知道这个错误与我尝试重构事物的方式有关。我相信这与尝试DB
在抽象类的构造函数中访问 Facade 有关(因为DB
在同一类中的其他方法中访问很好)。任何解释都将不胜感激 - 我很好奇为什么它不起作用。
我已经将它恢复为原始代码(这很好,真的)并且测试再次通过了!
哦,如果你想查看我的测试,它们是:
namespace Tests\Repositories;
use TestCase;
use App\Repositories\UserRepository;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseMigrations;
class UserRepositoryTest extends TestCase
{
use DatabaseMigrations;
private $repository;
public function __construct()
{
$this->repository = new UserRepository();
}
public function newUser()
{
return new User([
'name' => 'Joe',
'username' => 'joe',
'password' => bcrypt('password'),
'email' => 'joe@apple.com'
]);
}
public function test_all_method_returns_all_users()
{
$this->assertNotNull($this->repository->all());
}
public function test_create_user()
{
$this->assertTrue($this->repository->create($this->newUser()));
}
public function test_update_user()
{
// Arrange
$user = $this->newUser();
// Act
$this->repository->create($user);
$user->name = 'Jack';
// Assert
$this->assertTrue((integer)$this->repository->update($user) === 1);
}
public function test_delete_user()
{
// Arrange
$user = $this->newUser();
// Act
$this->repository->create($user);
// Assert
$this->assertTrue((integer)$this->repository->delete($user) === 1);
}
public function test_find_user()
{
// Arrange
$user = $this->newUser();
// Act
$this->repository->create($user);
// Assert
$this->assertInstanceOf(User::class, $this->repository->find($user->id));
}
}